【问题标题】:multiprocessing -> pathos.multiprocessing and windows多处理-> pathos.multiprocessing 和 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'])

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

【问题讨论】:

    标签: python multiprocessing pickle dill pathos


    【解决方案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 中将其冒泡是否有意义。
    猜你喜欢
    • 2014-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-18
    • 1970-01-01
    • 1970-01-01
    • 2018-06-29
    • 2020-06-27
    相关资源
    最近更新 更多