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

11

根据我的实验,我猜想答案是否定的。但是也许通过对futures模块进行一些更改可能是可能的。

我想提交一个工作器,它本身创建一个执行程序并提交工作。我想将第二个future返回给主进程。我有这个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))

我的问题是:是否有安全的方法可以通过多进程管道发送future对象,并在其完成后能够接收该值。似乎我可能需要设置另一个类似于执行程序的结构,以便通过另一个管道监听结果。


我对Python的concurrent库不是特别熟悉,但最近我一直在研究Ray。从我对你的问题的理解来看(诚然并不是很好,这也是我没有提交答案的原因之一),如果你愿意超越标准库进行查找,Ray很可能能够解决你的问题。你可以在这里阅读相关信息:https://rise.cs.berkeley.edu/projects/ray/ - PMende
1个回答

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接