多处理 - 池分配

时间:2012-04-27 09:27:53

标签: python multiprocessing pool

我在python中注意到池分配的这种行为。即使我在池中有20个进程,当我为8个进程执行map_async时,我只执行4个进程而不是执行所有进程。当那4个完成时,它再发送两个,然后当这两个完成时发送一个。

当我向它投掷超过20时,它会全部运行20,直到它在队列中开始变得少于20时,重复上述行为。

我认为这是故意的,但看起来很奇怪。我的目标是在请求进入后立即处理,显然这种行为不合适。

将python 2.6与billiard一起用于maxtasksperchild支持

任何想法如何改进它?

代码:

mypool = pool.Pool(processes=settings['num-processes'], initializer=StartChild, maxtasksperchild=10)

while True:
    lines = DbData.GetAll()
    if len(lines) > 0:
        print 'Starting to process: ', len(lines), ' urls'
        Res = mypool.map_async(RunChild, lines)
        Returns = Res.get(None)
        print 'Pool returns: ', idx, Returns
    else:
        time.sleep(0.5)

1 个答案:

答案 0 :(得分:2)

我在Python中处理多处理的一种方法如下:

我有数据,我想使用函数function() 首先,我创建一个多处理子类:

import multiprocessing

class ProcessThread(multiprocessing.Process):
    def __init__(self, id_t, inputqueue, idqueue, function, resultqueue):
        self.id_t = id_t
        self.inputlist = inputqueue
        self.idqueue = idqueue
        self.function = function
        self.resultqueue = resultqueue

        multiprocessing.Process.__init__(self)

    def run(self):
        s = "process number: " + str(self.id_t) + " starting"
        print s
        result = []

        while self.inputqueue.qsize() > 0
            try:
                inp = self.inputqueue.get()
            except Exception:
                pass
            result = self.function(inp)
            while 1:
               try:
                   self.resultqueue.put([self.id,])
               except Exception:
                   pass
               else:
                   break
            self.idqueue.put(id)
            return

和主要功能:

inputqueue = multiprocessing.Queue()
resultqueue = multiprocessing.Queue()
idqueue = multiprocessing.Queue()

def function(data):
    print data # or what you want

for datum in data:
    inputqueue.put(datum)

for i in xrange(nbprocess):
    ProcessThread(i, inputqueue, idqueue, function, resultqueue).start()

最后得到结果:

results = []
while idqueue.qsize() < nbprocess:
    pass
while resultqueue.qsize() > 0:
    results.append(resultqueue.get())

通过这种方式,您可以完美地控制附加过程和其他内容的内容。 仅当每个数据的计算非常慢(<1,2秒)时,使用多处理inputqueue是一种有效的技术,因为不同进程对队列的并发访问(这就是我使用异常的原因)。如果您的函数计算速度非常快,请考虑在bgining中仅将数据拆分一次,并在开始时为每个进程放置数据集块。