并行化递归python



我现在正在处理一个大数据集。我的输入将是4个不同的数据集,我必须对每个数据集应用一个特定的函数。因此,我所做的是读取所有四个数据集,并使用pool.map将函数并行应用于每个数据集。因此,现在我有了一个父进程和4个子进程。在此之前一切都很好。

Q1.现在每个过程中发生了什么。在我对每个数据集应用的函数中,我将每个元组与其他元组进行比较,因此这是一种递归。有没有办法使其平行,因为这种比较可能需要很长时间,因为数据集会很大。如何制作它,因为它已经是一个子进程了?有没有可能在子进程中再次并行化它,因为我有更多的处理器,所以我想利用它

Q2.对于这个递归任务的并行化,我想的是,如果我将元组x与元组y(每个元组与所有其他元组)进行比较,我可以为x生成块,每个块与y进行比较。我想这可以用两个"for循环"来完成。有什么建议吗?

Re:Q1,如果您使用multiprocessing.Pool创建子进程,那么不,辅助进程不能有子进程。尝试创建一个会引发异常:

AssertionError: daemonic processes are not allowed to have children

原因说得很清楚——Pool中的进程是守护进程,而守护进程不能有子进程。原因是终止父进程将终止其守护进程子进程,但守护进程子级将无法终止子进程,这将留下孤立进程。这在文件中有说明:

请注意,守护进程不允许创建子进程。否则,如果守护进程在其父进程退出时终止。

您可以通过父进程创建一组非守护进程Process对象而不是使用Pool来解决此问题。然后,每个孩子都可以创建自己的multiprocessing.Pool:

import multiprocessing
def subf(x):
    print "in subf"
def f(x):
    print "in f"
    p = multiprocessing.Pool(2)
    p.map(subf, range(2))

if __name__ == "__main__":
    processes = []
    for i in range(2):
        proc = multiprocessing.Process(target=f, args=(i,))
        proc.start()
        processes.append(proc)

输出:

in f
in f
in subf
in subf
in subf
in subf

这种方法似乎对您来说还可以,因为您的初始数据集只包含四个项目。您可以在数据集中为每个项目创建一个Process,并且仍然有一些空闲CPU可供每个子进程在小型Pool中使用。

回复:Q2,听起来您可以使用itertools.product为要比较的每对元组创建一个大型可迭代对象。然后,您可以使用pool.map对每对进行并行比较。下面是一个例子,展示了它是如何工作的:

def f(x):
    print(x)
if __name__ == "__main__":
    # Create two lists of tuples, like your use-case
    x = zip(range(3), range(3,6))
    y = zip(range(6, 9), range(9, 12))
    pool = multiprocessing.Pool()
    pool.map(f, itertools.product(x, y))

输出:

((0, 3), (6, 9))
((0, 3), (7, 10))
((0, 3), (8, 11))
((1, 4), (6, 9))
((1, 4), (7, 10))
((1, 4), (8, 11))
((2, 5), (6, 9))
((2, 5), (8, 11))
((2, 5), (7, 10))

最新更新