是否可以在进程之间传递Python Future对象?

时间:2017-07-07 16:42:20

标签: python concurrent.futures

根据我的实验,我猜测答案是否定的。但也许有可能对期货模块进行一些改变。

我想提交一个自己创建执行者并提交工作的工人。我想把第二个未来归还给主流程。我有这个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))

我的问题是:是否有任何安全的方法可以在多处理管道中发送未来对象,并且能够在完成后接收该值。看起来我可能需要设置另一个类似于执行器的构造,用于侦听另一个管道上的结果。

1 个答案:

答案 0 :(得分:4)

我当前的设置是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的可调用对象中调用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