多处理-> pathos.multiprocessing 和 windows
Posted
技术标签:
【中文标题】多处理-> pathos.multiprocessing 和 windows【英文标题】:multiprocessing -> pathos.multiprocessing and windows 【发布时间】:2015-10-22 08:30:52 【问题描述】:我目前在 python 中使用标准的多处理来生成一堆将无限期运行的进程。我并不特别关心性能。每个线程只是在观察文件系统上的不同变化,并在文件被修改时采取适当的行动。
目前,我有一个在 Linux 中可以满足我需求的解决方案。我有一个函数和参数字典,如下所示:
job_dict['func1'] = 'target': func1, 'args': (args,)
对于每一个,我创建一个流程:
import multiprocessing
for k in job_dict.keys():
jobs[k] = multiprocessing.Process(target=job_dict[k]['target'],
args=job_dict[k]['args'])
有了这个,我可以跟踪每一个正在运行的任务,并在必要时重新启动因任何原因崩溃的作业。
这在 Windows 中不起作用。我使用的许多函数都是包装器,使用各种functools
函数,并且我收到有关无法序列化函数的消息(请参阅What can multiprocessing and dill do together?)。我还没有弄清楚为什么我在 Linux 中没有出现此错误,但在 Windows 中却出现了。
如果我在 Windows 中启动我的进程之前导入 dill
,我不会收到序列化错误。然而,这些进程实际上并没有做任何事情。我不知道为什么。
然后我切换到pathos
中的多处理实现,但在标准multiprocessing
模块中没有找到简单的Process
类的模拟。我能够使用pathos.pools.ThreadPool
为每个作业生成线程。我敢肯定,这不是 map 的预期用途,但它启动了所有线程,并且它们在 Windows 中运行:
import pathos
tp = pathos.pools.ThreadPool()
for k in job_dict.keys():
tp.uimap(job_dict[k]['target'], job_dict[k]['args'])
但是,现在我不确定如何监视线程是否仍然处于活动状态,我正在寻找它以便我可以重新启动由于某种原因而崩溃的线程。有什么建议吗?
【问题讨论】:
【参考方案1】:我是pathos
和dill
的作者。 Process
类深埋在pathos
的pathos.helpers.mp.process.Process
中,其中mp
本身就是multiprocessing
库的实际分支。 multiprocessing
中的所有内容都应该可以从那里访问。
关于pathos
的另一件事是,它会为您保持pool
的活动状态,直到您将其从保持状态中移除。这有助于减少创建“新”池的开销。要删除池,您可以:
>>> # create
>>> p = pathos.pools.ProcessPool()
>>> # remove
>>> p.clear()
但是,Process
没有这样的机制。
对于multiprocessing
,windows 与 Linux 和 Macintosh 不同……因为 windows 没有像在 linux 上那样正确的 fork
……linux 可以跨进程共享对象,而在 windows 上没有共享……它基本上是一个完全创建了独立的新进程……因此,序列化必须更好地让对象传递给另一个进程——就像你将对象发送到另一台计算机一样。在 linux 上,您必须这样做才能获得相同的行为:
def check(obj, *args, **kwds):
"""check pickling of an object across another process"""
import subprocess
fail = True
try:
_x = dill.dumps(x, *args, **kwds)
fail = False
finally:
if fail:
print "DUMP FAILED"
msg = "python -c import dill; print dill.loads(%s)" % repr(_x)
print "SUCCESS" if not subprocess.call(msg.split(None,2)) else "LOAD FAILED"
【讨论】:
谢谢。我读过你将 pathos 描述为多处理库的一个分支,并在 pathos 中寻找它,但没有注意到它藏在 helpers 中。我也很欣赏为什么多处理在 windows 和 linux 中表现不同的解释。我用来自 pathos 的调用替换了我的 mutliprocessing.Process 调用,但得到的行为与我在使用标准多处理调用之前导入 dill 时的行为相同。我将继续使用它,但也可能会重新评估我更普遍地解决这个问题的方式。 使用multiprocessing
和第一次导入dill
时出现相同行为的原因是dill
可以覆盖python pickle
,但multiprocessing
使用 C-python pickle
... 所以它必须被 fork 才能使用 dill
。
……也许我把叉子埋得太深了。但是,它可以作为名为@987654343@ 的独立包提供。我将不得不考虑在pathos
中将其冒泡是否有意义。以上是关于多处理-> pathos.multiprocessing 和 windows的主要内容,如果未能解决你的问题,请参考以下文章
多处理-> pathos.multiprocessing 和 windows
Python 多处理 PicklingError:无法腌制 <type 'function'>
使用多处理 Pool.map() 时无法腌制 <type 'instancemethod'>