我有两段代码,代表我正在调试的更复杂的场景。我想知道他们是否在技术上是等价的,如果不是,为什么。你知道吗
第一个:
import time
from concurrent.futures import ThreadPoolExecutor
def cb(res):
print("done", res)
def foo():
time.sleep(3)
res = 5
cb(res)
return res
with ThreadPoolExecutor(max_workers=2) as executor:
future = executor.submit(foo)
print(future.result())
第二个:
def cb2(fut):
print("done", fut.result())
def foo2():
time.sleep(3)
return 5
with ThreadPoolExecutor(max_workers=2) as executor:
future = executor.submit(foo2)
future.add_done_callback(cb2)
print(future.result())
问题的核心是:我需要调用一个sync,慢操作(这里用sleep表示)。当该操作完成时,我必须执行后续的快速操作。在第一段代码中,我将这些操作放在sync slow操作之后。在第二段代码中,我将其放入回调中。你知道吗
在实现方面,我怀疑未来会创建一个次线程,在次线程中运行代码,这个次线程会在sync slow操作时停止。一旦此操作完成,辅助线程将继续运行,它可以通过执行后续代码或调用回调来继续运行。我认为这两段代码没有区别(除了添加回调允许从外部注入代码这一事实,增加了灵活性),但我可能错了,因此问题来了。你知道吗
请注意,我确实理解,在第一种情况下,当未来仍未解决时调用print,在第二种情况下调用print,但假定状态不相关。你知道吗
https://gist.github.com/mangecoeur/9540178https://docs.python.org/3.4/library/concurrent.futures.html
与concurrent.futures.processPool执行器()作为执行人: 结果=执行者.map(函数,iterable)
你知道吗执行者.map(有趣,[数据]*10)
池=多处理池() 池.map(…)
与并发.futures.ThreadPoolExecutor()作为执行人: 结果=执行者.map(函数,iterable)
这两个例子在事件排序方面并不相等。 让我们看看未来的生命周期。大致上是这样的(从cpython的来源逆向工程):
submit()
的函数在该线程中被调用当您执行语句
print(future.result())
时,您的主线程阻塞并成为未来的服务员。在future切换到FINISHED之后,但在回调开始执行之前,它就被解除了阻塞。这意味着您无法预测在控制台中打印的第一步是什么-print
在任何回调中,或者print(future(result))
-它们现在是并行执行的。如果在等待future.result()
完成后在回调和主线程中处理相同的数据,则很可能会导致数据损坏。你知道吗相关问题 更多 >
编程相关推荐