我对下面的代码有一个非常奇怪的问题。当numrows = 10
进程循环完成并继续完成时。如果增长列表变大,就会陷入僵局。为什么会这样,我该如何解决?
import multiprocessing, time, sys
# ----------------- Calculation Engine -------------------
def feed(queue, parlist):
for par in parlist:
queue.put(par)
def calc(queueIn, queueOut):
while True:
try:
par = queueIn.get(block = False)
print "Project ID: %s started. " % par
res = doCalculation(par)
queueOut.put(res)
except:
break
def write(queue, fname):
print 'Started to write to file'
fhandle = open(fname, "w")
while True:
try:
res = queue.get(block = False)
for m in res:
print >>fhandle, m
except:
break
fhandle.close()
print 'Complete writing to the file'
def doCalculation(project_ID):
numrows = 100
toFileRowList = []
for i in range(numrows):
toFileRowList.append([project_ID]*100)
print "%s %s" % (multiprocessing.current_process().name, i)
return toFileRowList
def main():
parlist = [276, 266]
nthreads = multiprocessing.cpu_count()
workerQueue = multiprocessing.Queue()
writerQueue = multiprocessing.Queue()
feedProc = multiprocessing.Process(target = feed , args = (workerQueue, parlist))
calcProc = [multiprocessing.Process(target = calc , args = (workerQueue, writerQueue)) for i in range(nthreads)]
writProc = multiprocessing.Process(target = write, args = (writerQueue, 'somefile.csv'))
feedProc.start()
feedProc.join ()
for p in calcProc:
p.start()
for p in calcProc:
p.join()
writProc.start()
writProc.join()
if __name__=='__main__':
sys.exit(main())
答案 0 :(得分:1)
我认为问题是Queue缓冲区被填满,所以你需要先从队列中读取,然后再添加其他内容。
例如,在feed
主题中,您有:
queue.put(par)
如果你在没有读取的情况下继续放入很多东西,这会导致它被阻塞,直到缓冲区被释放,但问题是你只释放了calc
线程中的缓冲区,而后者又无法启动在加入阻止feed
主题之前。
因此,为了使feed
线程完成,应释放缓冲区,但在线程完成之前不会释放缓冲区:)
尝试更多地组织您的队列访问。
答案 1 :(得分:1)
feedProc和writeProc实际上并不与您的程序的其余部分并行运行。当你有
proc.start()
proc.join ()
你开始这个过程,然后,join()
你立即等待它完成。在这种情况下,多处理没有任何好处,只有开销。尝试在加入之前立即启动所有进程。这也会导致您的队列被清空常规,并且您不会死锁。