多处理,写入文件,以及大循环上的死锁

时间:2012-06-07 14:43:00

标签: python multiprocessing

我对下面的代码有一个非常奇怪的问题。当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())

2 个答案:

答案 0 :(得分:1)

我认为问题是Queue缓冲区被填满,所以你需要先从队列中读取,然后再添加其他内容。 例如,在feed主题中,您有:

queue.put(par)

如果你在没有读取的情况下继续放入很多东西,这会导致它被阻塞,直到缓冲区被释放,但问题是你只释放了calc线程中的缓冲区,而后者又无法启动在加入阻止feed主题之前。

因此,为了使feed线程完成,应释放缓冲区,但在线程完成之前不会释放缓冲区:)

尝试更多地组织您的队列访问。

答案 1 :(得分:1)

feedProc和writeProc实际上并不与您的程序的其余部分并行运行。当你有

proc.start()
proc.join ()

你开始这个过程,然后,join()你立即等待它完成。在这种情况下,多处理没有任何好处,只有开销。尝试在加入之前立即启动所有进程。这也会导致您的队列被清空常规,并且您不会死锁。