Python多处理、进程和池之间的差异、数据的酸洗

Python多处理、进程和池之间的差异、数据的酸洗,python,multiprocessing,pickle,Python,Multiprocessing,Pickle,我想知道,当涉及到酸洗和分配作业时,启动一个工人池来并行管理一项任务或启动单个流程有什么区别 我确实有一个任务(这里是做我的工作),其对象不能被pickle。因此,我无法启动一个工人池来并行执行任务。以下代码段不起作用,其中,iterator对do\u my\u job的不同参数设置进行迭代: import multiprocessing as multip mpool = multip.Pool(ncores) mpool.map(do_my_job, iterator) mpool.clo

我想知道,当涉及到酸洗和分配作业时,启动一个工人池来并行管理一项任务或启动单个流程有什么区别

我确实有一个任务(这里是
做我的工作
),其对象不能被pickle。因此,我无法启动一个工人池来并行执行任务。以下代码段不起作用,其中,
iterator
do\u my\u job
的不同参数设置进行迭代:

import multiprocessing as multip

mpool = multip.Pool(ncores)
mpool.map(do_my_job, iterator)
mpool.close()
mpool.join()
但是,以下代码片段确实有效:

import time
import multiprocessing as multip

keep_running=True
process_list = []

while len(process_list)>0 or keep_running:

    terminated_procs = []
    for idx, proc in enumerate(process_list):

        if not proc.is_alive():
            terminated_procs.append(idx)

    for terminated_proc in terminated_procs:
        process_list.pop(terminated_proc)

    if len(process_list) < ncores and keep_running:
        try:
            task = iterator.next()
            proc = multip.Process(target=do_my_job,
                                                   args=(task,))

            proc.start()
            process_list.append(proc)
        except StopIteration:
            keep_running=False


    time.sleep(0.1)
导入时间
将多处理导入为多处理
保持运行=真
进程列表=[]
len(进程列表)>0或保持运行时:
终止的\u进程=[]
对于idx,枚举中的proc(进程列表):
如果没有,进程是否处于活动状态():
终止的进程附加(idx)
对于终止的\u进程中的终止的\u进程:
进程列表.pop(终止进程)
如果len(进程列表)恢复并保持运行:
尝试:
task=iterator.next()
进程=多进程(目标=做我的工作,
args=(任务,))
程序启动()
进程列表追加(proc)
除停止迭代外:
保持运行=错误
睡眠时间(0.1)

在后一种情况下,我的工作是如何分配到各个进程的?在流程启动之前,是否没有酸洗任务和所有相关对象的步骤?如果没有,任务和对象是如何传递给新进程的?

当您叉入新进程时,子进程将继承其父进程的数据。因此,如果父级在分叉之前定义了一个变量,子级将能够看到它,因为它是自己的变量。在
fork
syscall之后,子进程和父进程应该使用一些IPC在它们之间共享数据。 当您创建一个
时,您正在分叉N个进程,然后,当您调用
映射
时,您将数据传递给它们。但是,由于进程已经分叉,共享此数据的唯一方法是使用IPC,这涉及到对象的“酸洗”。在后一种情况下,您是在创建数据后进行分叉,因此子进程能够像访问自己的数据一样访问它。
我认为你能做的最好的事情就是让你的对象“可拾取”。

继承的数据被复制,对吗?所以无论子进程对数据做了什么,都不会修改父类的数据?!不幸的是,我不能使我的对象“可拾取”,因为它的一部分来自第三方应用程序。通常它是“写时复制”。子对象和父对象将共享相同的“内存”,直到其中一个尝试写入,然后复制。@smcatepillar,主程序如何访问这些第三方对象?您可以在池进程中使用相同类型的代码来访问它们,可能是在进程初始化函数中。这里没有足够的细节来充实它。在极端情况下,您可以将代码作为字符串来访问它们,并在池进程中
exec
该字符串。总有其他选择;-)我正在编写一个API,以便更轻松地存储数据和处理BRIAN()实验。API应允许轻松并行处理多个网络。这必须处理在并行参数探索之前预构建和预运行网络的情况。问题是,有时BRIAN网络不能被腌制。因此,所有池进程都需要重建网络。有时这样做代价太高,尤其是当你可以做一次而不是一千次的时候。我的意思是,我上面的代码建议比使用池差多少?这是一个困难的问题,你应该做一些测试,也许可以使用
timeit