7

我正在尝试为自己的目的实现这个多处理教程。起初我认为它不能很好地扩展,但是当我做了一个可重现的例子时,我发现如果项目列表超过 124,它似乎永远不会返回答案。x = 124它在 0.4 秒内运行,但是当我将它设置为它时,它x = 125永远不会完成。我在 Windows 7 上运行 Python 2.7。

from multiprocessing import Lock, Process, Queue, current_process
import time

class Testclass(object):
    def __init__(self, x):
        self.x = x

def toyfunction(testclass):
    testclass.product = testclass.x * testclass.x
    return testclass


def worker(work_queue, done_queue):
    try:
        for testclass in iter(work_queue.get, 'STOP'):
            print(testclass.counter)
            newtestclass = toyfunction(testclass)
            done_queue.put(newtestclass)

    except:
        print('error')

    return True

def main(x):

    counter = 1

    database = []
    while counter <= x:
        database.append(Testclass(10))
        counter += 1
        print(counter)



    workers = 8
    work_queue = Queue()
    done_queue = Queue()
    processes = []

    start = time.clock()
    counter = 1

    for testclass in database:
        testclass.counter = counter
        work_queue.put(testclass)
        counter += 1
        print(counter)


    print('items loaded')
    for w in range(workers):
        p = Process(target=worker, args=(work_queue, done_queue))
        p.start()
        processes.append(p)
        work_queue.put('STOP')

    for p in processes:
        p.join()

    done_queue.put('STOP')

    newdatabase = []
    for testclass in iter(done_queue.get, 'STOP'):
        newdatabase.append(testclass)

    print(time.clock()-start)
    print("Done")
    return(newdatabase)

if __name__ == '__main__':
    database = main(124)
    database2 = main(125)
4

1 回答 1

6

好的!从文档

警告 如上所述,如果子进程已将项目放入队列(并且它没有使用 JoinableQueue.cancel_join_thread),那么该进程将不会终止,直到所有缓冲项目都已刷新到管道。这意味着如果您尝试加入该进程,您可能会遇到死锁,除非您确定已放入队列的所有项目都已被消耗。类似地,如果子进程是非守护进程,则父进程在尝试加入其所有非守护子进程时可能会挂起退出。请注意,使用管理器创建的队列不存在此问题。请参阅编程指南。

正如我之前在评论中指出的那样,代码尝试在队列被耗尽之前.join()进行处理——并且在以一种时髦的方式更改代码以确保在'ing之前被耗尽之后,代码对于一百万个项目运行良好。done_queuedone_queue.join()

所以这是一个飞行员错误的案例,虽然很模糊。至于为什么行为取决于传递给 的数字main(x),它是不可预测的:它取决于内部缓冲是如何完成的。好好玩 ;-)

于 2013-09-29T03:17:26.873 回答