在 python 中创建并行 for 循环

Creating parallel for loop in python

我查看了类似的问题,尤其是 this 答案。我的情况有点不同,所以问一下。

import os
import multiprocessing as mp

def fun1(str1):
 #function def

if __name__ == '__main__':


    pl1 = mp.Pool(processes=2)
    pl2 = mp.Pool(processes=2)

for (d1,d2,d3) in os.walk('dirname'):
    for d4 in d2:
        pl1.map(fun1,d4)

    for d5 in d3:
        pl2 .map(fun1,d5)
#

我正在获取文件和目录名称作为字符串并将其传递给 fun1()。但问题是,如果我使用 pl1.map(fun1,d4),它看起来像 python 分隔每个字符串字符并将单个字符传递给 fun1()。我希望将整个字符串 d4,d5 传递给 fun1() 并并行传递以减少 运行 时间。我创建了 2 个池 pl1,pl2 以便它们可以在顶层 for 循环中单独使用而不会引起任何问题。

知道如何解决这个问题吗?

来自 multiprocessing doc 的 Pool.map 方法:

This method chops the iterable into a number of chunks which it submits to the process pool as separate tasks.

因此它将字符串 d4 视为可迭代的,并按字母(一个接一个)将其发送到进程。您可能正在寻找 Pool.apply_async:

pl1.apply_async(fun1, d4)

或者简单地将 d2 传递给池(不使用 for 循环“for d4 in d2”):

pl1.map(fun1, d2)

编辑 - 最终代码可能如下所示:

for (d1,d2,d3) in os.walk('dirname'):
    pl1.map(fun1,d2)
    pl2.map(fun1,d3)

据我了解,多处理模块是通过在幕后使用 C 来优化的。因此,使用 ctypes 可能是您问题的解决方案:

from ctypes import c_char_p
from multiprocessing import Process, Manager, Value, Pool

manager = Manager()
pool = Pool(processes=2)
pool2 = Pool(processes=2)
for (d1,d2,d3) in os.walk('dirname'):
    for d4 in d2:
        d4_string = manager.Value(c_char_p, d4)
        pool.map(fun1, d4_string)
        pool.join()

    for d5 in d3:
        d4_string = manager.Value(c_char_p, d4)
        pool2.map(fun1, d4_string)
        pool2.join()