是否可以将多个args传递给multiprocessing.pool?

时间:2012-10-22 08:36:34

标签: python multiprocessing

  

可能重复:
  Python multiprocessing pool.map for multiple arguments

我想在multiprocessing.Pool中为子进程提供两个参数?我觉得我正在上坡。有可能是2个args,或者一个元组,还是......?它似乎对一些人来说很好,正确地传递出两个文件名(in和out),但是然后barfs意外地在一个变量点。可悲的是它并没有真正起作用,因为输出文件都是空的 - 如果我直接调用它或者单个处理它就不会发生这种情况。还有另一个复杂因素,被调用的例程在另一个导入的模块中。本地化作为'foo'存根模块确实解决了问题,但它只打印了args,而不是尝试做任何实际的工作。

这可能是顽固地拒绝学习如何使用队列的漫长道路,但我只是想确认一下我不会在任何地方推进我正在使用的道路。

fixtures/txt_data/AAD.txt obj/txt_data/AAD.txt
fixtures/txt_data/ANZSMW.txt obj/txt_data/ANZSMW.txt
fixtures/txt_data/BENPA.txt obj/txt_data/BENPA.txt
fixtures/txt_data/CBAIZQ.txt obj/txt_data/CBAIZQ.txt
Traceback (most recent call last):
  File "./jobflow.py", line 60, in <module>
    main()
  File "./jobflow.py", line 57, in main
    args.func(args)
  File "./jobflow.py", line 40, in market
    pool.map(foo, market_files())
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/multiprocessing/pool.py", line 225, in map
  return self.map_async(func, iterable, chunksize).get()
File     "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/multiprocessing/pool.py", line 522, in get
raise self._value
TypeError: function takes exactly 1 argument (2 given)
fixtures/txt_data/CSDO.txt obj/txt_data/CSDO.txt
fixtures/txt_data/EMB.txt obj/txt_data/EMB.txt
fixtures/txt_data/GGG.txt obj/txt_data/GGG.txt
fixtures/txt_data/IDL.txt obj/txt_data/IDL.txt

这是一个错误示例。它在文件耗尽之前停止。它或者呻吟它想要2个args,但是当我改变它以试图通过两个args时只得到1:

def foo(c):
    a, b, = c
    print a, b
    market2.file_main((a, b))  # does comment/uncommenting this break it only because it's in another python file?

def market(args):
    """
    read raw ticker data files and output nice, clean, more valid ticker data files
    """
    pool = multiprocessing.Pool()

    class market_files(object):
        for infile in args.infiles:
            outfile = os.path.join(args.outdir, os.path.basename(infile))
            yield (infile, outfile)

    pool.map(foo, market_files())

1 个答案:

答案 0 :(得分:3)

哦,等等,它确实有效,但不是直接传递多个args,而是将它们放入元组中。

我通过在每次迭代中生成一个新的Processp.start()来实现它,这会产生一些荒谬的进程;-)但确实吞下了多个参数。

从那里开始工作我将iterable简化为一个列表(现在我已经得到了迭代可能很好),但我认为最重要的是将args作为元组传递。一定是在切割室地板上有太多混乱的情况之一,看看有效的解决方案。

所以在控制器中我有:

    arglist = []
    for infile in args.infiles:
        outfile = os.path.join(args.outdir, os.path.basename(infile))
        arglist.append((infile, outfile))

    pool = multiprocessing.Pool()
    p = pool.map(func=market2.process, iterable=arglist)

在模块中:

    def process(x):
        infile, outfile = x
        instream = open(infile, 'rB')
        outstream = open(outfile, 'wB')
        main(instream, outstream)
        instream.close()
        outstream.close()

4核性能(分钟):

  • 单线程= 3:54
  • 使用subprocess = 4:52(我认为它默认会阻塞,所以可以计算)
  • 同时使用数千Process = 2:41(每个进程饱和所有内核,每个进程1-4%cpu)
  • 使用Pool = 2:13