根据我的实验,我猜这个答案是否定的。但也许有可能对期货模块进行一些改变。
我想提交一个自己创建执行者并提交工作的工人。我想把第二个未来归还给主流程。我有这个MWE,它不起作用,因为f2
对象在通过多处理发送时可能会与其父执行器解除关联。 (如果两个执行程序都是ThreadPoolExecutor,它确实有效,因为永远不会复制f2
对象)。
from concurrent.futures import ProcessPoolExecutor, ThreadPoolExecutor
import time
def job1():
try:
ex2 = ThreadPoolExecutor()
time.sleep(2)
f2 = ex2.submit(job2)
finally:
ex2.shutdown(wait=False)
return f2
def job2():
time.sleep(2)
return 'done'
try:
ex1 = ProcessPoolExecutor()
f1 = ex1.submit(job1)
finally:
ex1.shutdown(wait=False)
print('f1 = {!r}'.format(f1))
f2 = f1.result()
print('f1 = {!r}'.format(f1))
print('f2 = {!r}'.format(f2))
我的问题是:是否有任何安全的方法可以在多处理管道中发送未来的对象,并且能够在完成后接收该值。看起来我可能需要设置另一个类似于执行器的构造,用于侦听另一个管道上的结果。
我目前的设置是Ubuntu 16.04.5 LTS和Python 3.6.5。运行上面发布的代码时收到以下错误:
f2 = f1.result()
其次是
concurrent.futures.process.BrokenProcessPool: A process in the process pool was terminated abruptly while the future was running or pending.
浏览Python文档,我在17.4.3下找到了。 ProcessPoolExecutor即
“从提交给ProcessPoolExecutor的callable调用Executor或Future方法将导致死锁。”
此外,在
class concurrent.futures.ProcessPoolExecutor(max_workers=None)
我还发现了以下内容:
“在版本3.3中更改:当其中一个工作进程突然终止时,现在引发了BrokenProcessPool错误。以前,行为未定义,但对执行程序或其未来的操作通常会冻结或死锁。”
此外,根据定义,ProcessPoolExecutor关闭全局解释器锁,将其打开以供其他进程访问。
要回答关于是否有任何安全方法可以通过多处理管道发送未来对象并在另一端接收它的问题,我会对标准库说不。
参考文献:
https://docs.python.org/3.6/library/concurrent.futures.html#processpoolexecutor
https://docs.python.org/3.6/glossary.html#term-global-interpreter-lock