多处理-> 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】:

我是pathosdill 的作者。 Process 类深埋在pathospathos.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 ……也许我把叉子埋得太深了。但是,它可以作为名为@9​​87654343@ 的独立包提供。我将不得不考虑在pathos 中将其冒泡是否有意义。

以上是关于多处理-> pathos.multiprocessing 和 windows的主要内容,如果未能解决你的问题,请参考以下文章

多处理-> pathos.multiprocessing 和 windows

Python 多处理 PicklingError:无法腌制 <type 'function'>

vue 多组件路由处理方法

使用多处理 Pool.map() 时无法腌制 <type 'instancemethod'>

Python多处理PicklingError:无法腌制<type'function'>

多线程通用处理队列类