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

Posted

技术标签:

【中文标题】是否可以在进程之间传递 Python Future 对象?【英文标题】:Is it possible to pass Python Future objects between processes? 【发布时间】:2017-12-12 01:19:34 【问题描述】:

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

我想提交一个自己创建执行器并提交工作的工作人员。我想将第二个未来返回到主进程。我有这个 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))

我的问题是:有什么安全的方法可以让我通过多处理管道发送一个未来的对象,并在它完成时接收它的值。似乎我可能需要设置另一个类似执行器的构造来侦听另一个管道上的结果。

【问题讨论】:

我对 Python 的 concurrent 库不是很熟悉,但我最近一直在研究 Ray。根据我对您的问题的了解(诚然,这不是很好,并且是我不提交答案的原因之一),如果您愿意向外看,Ray 很可能能够解决您的问题的标准库。你可以在这里阅读:rise.cs.berkeley.edu/projects/ray 【参考方案1】:

我当前的设置是 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

【讨论】:

以上是关于是否可以在进程之间传递 Python Future 对象?的主要内容,如果未能解决你的问题,请参考以下文章

在 python 进程之间传递二进制数据

Python NotImplementedError:无法在进程之间传递池对象

python 使用Python的多处理库在进程之间传递套接字的示例

2个应用程序之间的进程间通信

Python和Signal

线程与进程的区别