我正在使用大数据集。我的输入将是4个不同的数据集,我必须将特定的函数应用于每个数据集。所以我所做的就是读取所有四个数据集并使用pool.map并行地将函数应用于每个数据集。所以现在我有一个父母和4个孩子的过程。在此之前一切都很好。
Q1。现在每个过程中发生了什么。在我应用于每个数据集的函数中,我将每个元组与其他元组进行比较,因此它是一种递归。有没有办法让它并行,因为这种比较可能需要很长时间,因为数据集会很大。如何制作它因为它已经是一个子进程?是否有可能在子进程中再次并行化,因为我有更多的处理器,所以我想利用它。
Q2。对于这个递归任务的并行化我想到的是,如果我将元组x与元组y(每个元组与所有其他元组)进行比较,我可以为x创建块,并且每个块与y进行比较。我猜这可以通过两个for循环来完成。有什么建议怎么做?
答案 0 :(得分:4)
Re:Q1,如果您使用multiprocessing.Pool
创建子进程,则不然,工作进程无法生成子进程。尝试创建一个将引发异常:
AssertionError: daemonic processes are not allowed to have children
原因很清楚 - Pool
中的过程是守护进程,而守护进程无法生成孩子。这样做的原因是终止父进程将终止其守护进程的子进程,但守护进程的子进程将无法终止他们的子进程,这将留下孤立进程。这在documentation:
请注意,不允许守护进程创建子进程。 否则,守护进程会使其子女成为孤儿 当父进程退出时终止。
您可以通过父进程来创建一组非守护进程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
中使用。
Re: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))