多处理 -> pathos.multiprocessing 和 windows

multiprocessing -> pathos.multiprocessing and windows

我目前正在使用 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'])

有了这个,我可以跟踪每个正在 运行ning 的作业,并且在必要时重新启动因任何原因崩溃的作业。

这在 Windows 中不起作用。我使用的许多函数都是包装器,使用各种 functools 函数,我收到有关无法序列化函数的消息(请参阅 What can multiprocessing and dill do together?)。我还没弄明白为什么我在 Linux 中没有收到此错误,但在 Windows.

中却收到了

如果我在 Windows 中开始我的进程之前导入 dill,我不会收到序列化错误。但是,这些进程实际上并没有做任何事情。我不知道为什么。

然后我切换到 pathos 中的多处理实现,但没有在标准 multiprocessing 模块中找到简单 Process class 的模拟。我能够使用 pathos.pools.ThreadPool 为每个作业生成线程。这不是 map 的预期用途,我敢肯定,但它启动了所有线程,它们 运行 in Windows:

import pathos
tp = pathos.pools.ThreadPool()
for k in job_dict.keys():
    tp.uimap(job_dict[k]['target'], job_dict[k]['args'])

但是,现在我不确定如何监视线程​​是否仍然处于活动状态,我正在寻找它以便我可以重新启动由于某种原因而崩溃的线程。有什么建议吗?

我是 pathosdill 的作者。 Process class 深埋在 pathospathos.helpers.mp.process.Process 中,其中 mp 本身是 multiprocessing 库的实际分支。 multiprocessing 中的所有内容都应该可以从那里访问。

关于 pathos 的另一件事是,它会为您保持 pool 处于活动状态,直到您将其从保留状态中删除。这有助于减少创建 "new" 池的开销。要删除池,您可以执行以下操作:

>>> # create
>>> p = pathos.pools.ProcessPool()
>>> # remove
>>> p.clear()

但是 Process 没有这样的机制。

对于 multiprocessing,windows 与 Linux 和 Macintosh 不同……因为 windows 没有像 [=39] 那样的 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"