python - 这两个 python 代码是否等同于使用并发 future ?

标签 python multithreading

我有两段代码,代表我正在尝试调试的更复杂的场景。我想知道它们在技术上是否等效,如果不是,为什么。

第一个:

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表示)。该操作完成后,我必须执行后续的快速操作。在第一个代码中,我将这些操作紧跟在同步慢速操作之后。在第二个代码中,我把它放在回调中。

在实现上,我怀疑 future 会创建一个副线程,在副线程中运行代码,这个副线程会停在sync slow操作上。完成此操作后,辅助线程将继续运行,它可以通过执行后续代码或调用回调来继续运行。我看不出这两段代码有什么区别(除了添加回调允许从外部注入(inject)代码这一事实之外,增加了灵 active ),但我可能是错的,因此出现了这个问题。

请注意,我确实理解在第一种情况下,当 future 仍未解决时调用打印,而在第二种情况下,它被调用,但假设状态不相关。

最佳答案

这两个示例在事件排序方面并不相同。 让我们来看看 Future 的生命周期。大致是这样的(从 cpython 的源代码逆向工程):

  • 创造了 future
  • 它被添加到执行者的队列中
  • 它被线程池中的一些空闲/空闲线程从队列中弹出
  • 提供给 submit() 的函数在该线程中被调用
  • future 被标记为已完成
  • future 向所有服务员广播“状态改变”事件
  • 调用回调(仍在同一个工作线程中)
  • 工作线程变为空闲/空闲,并可能从队列中获取另一个 future

当您执行语句 print(future.result()) 时,您的主线程会阻塞并成为 future 的等待者。在 future 切换到 FINISHED 之后,但在回调开始执行之前,它会立即解除阻塞。这意味着您无法预测控制台中的打印先行 - print 在任何回调中,或 print(future(result)) - 它们现在并行执行.如果您在等待 future.result() 完成后在回调和主线程中处理相同的数据,则可能会损坏数据。

关于python - 这两个 python 代码是否等同于使用并发 future ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57523440/

相关文章:

java - 在这种情况下如何防止方法运行两次?

python - "cannot find the input table or query"SELECT 语句错误

python - Python中的执行顺序和编码风格

python - 如何根据分组值将字典插入数据框的行?

python - 使用 for 循环迭代并引用 lst[i] 时出现 TypeError/IndexError

c - 为什么网络连接中断会导致 stdin 上出现 EOF?

.net - 如果我启动了5个以上的线程,VB.NET应用程序将在服务器上崩溃。

c# - SemaphoreSlim 不会对并发请求进行排队,并且仍然允许双重预订

python - Django+heroku : django logs appear, 应用日志没有

python - 在python中使用threading/multiprocessing同时进行多个计算