【问题标题】:Futures generated by ThreadPoolExecutor do not behave asynchronouslyThreadPoolExecutor 生成的期货不会异步运行
【发布时间】:2023-01-30 21:00:55
【问题描述】:

我想创建一个在 ThreadPoolExecutor 上运行的期货列表,然后在它们完成评估后立即显示它们中的每一个。

预期结果是:每 3 秒打印 0、2、6、12 中的每一个。

但是,我在 12 秒后才得到结果,并且数字是模拟显示的。

from concurrent.futures import ThreadPoolExecutor
import time

def fnc(x, y):
    time.sleep(3)
    return x*y

futures = []
with ThreadPoolExecutor(max_workers=1) as executor:
    for i in range(0, 4):
        print(f"Submitting {i}")
        futures += [executor.submit(fnc, i, i+1)]

for f in futures:
    print(f.result())

【问题讨论】:

  • 你不打印结果直到全部线程已终止——即在 ThreadPoolExecutor 工作管理器代码块之外
  • 明白了,谢谢! @Pingu

标签: python python-3.x python-multiprocessing python-multithreading


【解决方案1】:

建立您提交的期货清单,然后使用as_completed()知道线程何时完成并且其结果可用。

from concurrent.futures import ThreadPoolExecutor, as_completed
import time

def fnc(x, y):
    time.sleep(3)
    return x*y

futures = []

with ThreadPoolExecutor(max_workers=1) as executor:
    for i in range(0, 4):
        print(f"Submitting {i}")
        futures += [executor.submit(fnc, i, i+1)]
    for future in as_completed(futures):
        print(future.result())

【讨论】:

    【解决方案2】:

    您在 ThreadPoolExecutor 上下文管理器之外的每个未来调用 result 方法,当您退出时,它会调用 __exit__ 方法:

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.shutdown(wait=True)
        return False
    

    shutdown 方法签名是:

    shutdown(self, wait=True, *, cancel_futures=False)
    

    文档说:

    Args:
         wait: If True then shutdown will not return until all running
               futures have finished executing and the resources used by the
               executor have been reclaimed.
         cancel_futures: If True then shutdown will cancel all pending
               futures. Futures that are completed or running will not be
               cancelled.
    

    我们可以看到默认情况下它会等到所有正在运行的 futures 和它们的资源也停止运行,并且 cancel_futures 默认获取值 False,因此我们是不是取消未决期货。

    通过在上下文管理器中移动 for 循环块来修复它:

    from concurrent.futures import ThreadPoolExecutor
    import time
    
    def fnc(x, y):
        time.sleep(3)
        return x*y
    
    futures = []
    with ThreadPoolExecutor(max_workers=1) as executor:
        for i in range(0, 4):
            print(f"Submitting {i}")
            futures += [executor.submit(fnc, i, i+1)]
        for f in futures:
            print(f.result())
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-16
      • 2022-10-30
      • 2019-11-16
      相关资源
      最近更新 更多