【问题标题】:Creating parallel for loop in python在python中创建并行for循环
【发布时间】:2019-01-31 02:15:29
【问题描述】:

我查看了类似的问题,尤其是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 循环中单独使用而不会造成任何问题。

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

【问题讨论】:

  • 小心,如果你在条件内声明了 pl1 和 pl2,但你在它外面循环,如果你导入文件,你可能会遇到问题,因为条件部分不会被执行
  • 谢谢,它们没有在条件内声明。

标签: python python-2.7 multiprocessing python-multiprocessing


【解决方案1】:

来自multiprocessing doc 用于 Pool.map 方法:

此方法将可迭代对象分成若干块,作为单独的任务提交给进程池。

因此它将字符串 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)

【讨论】:

  • apply_async 会利用n 进程池吗?使用多个进程是目标。
  • 使用我建议的第二个选项 - 删除 for 循环并使用 map(fun1,d2)... 但是是的,apply_async 在 for 循环中运行 fun1 在池中的处理方式与 @ 相同987654330@ 可以。换句话说,map 只是简单的for 循环的一个简短版本。 注意:您可能想使用map_async,因为简单的map 会等到第一个块 (d2) 完成后,才会在第二个线程池之后将启动 (d3)。使用map_async,两个线程池应该几乎同时启动,不要等到一个完成。
【解决方案2】:

据我了解,多处理模块通过在幕后使用 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()

【讨论】:

  • 如何创建进程池?
猜你喜欢
  • 2016-08-10
  • 1970-01-01
  • 1970-01-01
  • 2017-03-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多