Python多处理:如何强制执行命令执行的优先顺序

时间:2014-02-01 07:12:48

标签: python multiprocessing

我需要通过多处理运行一系列独立的子进程调用。我事先知道,其中一些工作的执行速度比其他工作慢。为了有效利用处理器时间,我认为首先将慢速作业排队是有意义的。这样我希望避免奇怪的情况,其中一个长时间运行的作业最后被安排,剩下的处理器空闲。在这种特殊情况下,实际结果是否按顺序产生并不重要(因为各个进程创建的文件仅在所有进程完成后才使用)。但重要的是,慢速工作首先/优先安排。我的第一个问题是,我该如何做到这一点?

即使在阅读multiprocessing documentationthis excellent post explaining the differences between map(), map_async() etc.后,我仍然有点困惑。因此,我的第二个问题是:在这种情况下,我应该使用Pool.map()而不是Pool.map_async(),还是其他什么?

我尝试了map()map_async(),但起初我没有观察到任何一种预期的行为。以下示例运行进程,除了创建文件和休眠之外没有太多工作。

import subprocess
import multiprocessing
import time
import os
import glob
import sys

NUM_PROCS = 2

def work(cmd):
    return subprocess.call(cmd, shell=True)

def generate_cmds(n=10):
    for i in xrange(n):
        yield "sleep 2 && touch %d.log" % (i)

def main():
    assert len(sys.argv)==2, ("missing arg: async=[0|1]")
    async = sys.argv[1]=='1'

    results = []
    pool = multiprocessing.Pool(processes=NUM_PROCS)
    if async:
        print "map_async()"
        p = pool.map_async(work, generate_cmds(), callback=results.extend) 
        p.wait()# or p.close() and p.join()
    else:
        print "map()"
        results = pool.map(work, generate_cmds())

    print "results: %s" % (results)
    for f in glob.glob("[0-9]*.log"):
        print f, time.strftime('%H:%M:%S', 
                               time.localtime(os.path.getmtime(f)))

if __name__ == "__main__":
    main()

我假设创建文件的时间戳应与map()的命令顺序匹配,因为所有进程大致需要相同的时间才能完成,但它们没有(如果我不玩) CHUNKSIZE)。似乎所有其他命令同时运行:

$ python subp.py 0
map()
results: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
0.log 14:36:57
1.log 14:36:59
2.log 14:36:57
3.log 14:36:59
4.log 14:37:01
5.log 14:37:03
6.log 14:37:01
7.log 14:37:03
8.log 14:37:05
9.log 14:37:07

我知道这可以通过使用1的chunksize来修复,但我不明白为什么(有人可以解释吗?)。我的最后一个问题是:这是否意味着我应该使用map_async(chunksize=1)作为我的设置?

谢谢, 安德烈亚斯

PS:我正在使用Python 2.7以防万一。

1 个答案:

答案 0 :(得分:0)

回答我自己的问题:

在我的情况下,无论我使用map()还是map_async()都没关系,因为结果的顺序并不重要。然而,排队顺序/执行顺序是如此,因此将chunksize设置为1非常重要(提供的链接yopy给了我最后的线索)。每个处理器将运行chunksize迭代,并自动确定chunksize。这可能会产生不必要的副作用,即慢速作业(排队第一)被分配给一个(或少数)处理器,而不是在几个处理器之间平均分配。

安德烈亚斯