我在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)
答案 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中仅将数据拆分一次,并在开始时为每个进程放置数据集块。