在pool.join()期间挂起异步处理队列

时间:2017-07-16 22:04:56

标签: python multiprocessing

在python docs上,它表示如果maxsize小于或等于零,则队列大小是无限的。我也试过maxsize=-1。但事实并非如此,程序将会挂起。因此,作为一种解决方法,我创建了多个Queues来使用。但这并不理想,因为我需要处理更大的列表,然后必须创建越来越多的Queue()并添加额外的代码来处理元素。

queue = Queue(maxsize=0)
queue2 = Queue(maxsize=0)
queue3 = Queue(maxsize=0)
PROCESS_COUNT = 6

def filter(aBigList):

    list_chunks = list(chunks(aBigList, PROCESS_COUNT))

    pool = multiprocessing.Pool(processes=PROCESS_COUNT)

    for chunk in list_chunks:
        pool.apply_async(func1, (chunk,))

    pool.close()
    pool.join()

    allFiltered = []

    # list of dicts
    while not queue.empty():
        allFiltered.append(queue.get())

    while not queue2.empty():
        allFiltered.append(queue2.get())

    while not queue3.empty():
        allFiltered.append(queue3.get())

    //do work with allFiltered

def func1(subList):

    SUBLIST_SPLIT = 3

    theChunks = list(chunks(subList, SUBLIST_SPLIT))

    for i in theChunks[0]:

        dictQ = updateDict(i)
        queue.put(dictQ)

    for x in theChunks[1]:

        dictQ = updateDict(x)
        queue2.put(dictQ)

    for y in theChunks[2]:

        dictQ = updateDict(y)
        queue3.put(dictQ)

1 个答案:

答案 0 :(得分:1)

您的问题发生是因为您在加入呼叫之前未处理echo 1...1; //10.1 。 当您使用Queue时,应在尝试加入进纸器进程之前将其清空。 multiprocessing.Queue等待放入Process的所有对象在终止之前被刷新。我不知道为什么即使对于大尺寸的Queue也是如此,但它可能与基础Queue对象的大小不够大这一事实有关。 因此,在os.pipe之前拨打get电话可以解决您的问题。

pool.join

一个问题是为什么你需要自己处理沟通?如果你考虑因素,你可以让PROCESS_COUNT = 6 def filter(aBigList): list_chunks = list(chunks(aBigList, PROCESS_COUNT)) pool = multiprocessing.Pool(processes=PROCESS_COUNT) result_queue = multiprocessing.Queue() async_result = [] for chunk in list_chunks: async_result.append(pool.apply_async( func1, (chunk, result_queue))) done = 0 while done < 3: res = queue.get() if res == None: done += 1 else: all_filtered.append(res) pool.close() pool.join() # do work with allFiltered def func1(sub_list, result_queue): # mapping function results = [] for i in sub_list: result_queue.append(updateDict(i)) result_queue.append(None) 为你管理:

Pool

这可以避免这种错误。

修改 最后,您甚至可以使用PROCESS_COUNT = 6 def filter(aBigList): list_chunks = list(chunks(aBigList, PROCESS_COUNT)) pool = multiprocessing.Pool(processes=PROCESS_COUNT) async_result = [] for chunk in list_chunks: async_result.append(pool.apply_async(func1, (chunk,))) pool.close() pool.join() # Reduce the result allFiltered = [res.get() for res in async_result] # do work with allFiltered def func1(sub_list): # mapping function results = [] for i in sub_list: results.append(updateDict(i)) return results 函数进一步减少代码,甚至可以处理chunksize。 如果你的块太大,你可能会在结果的酸洗过程中出错(如评论中所述)。因此,您可以使用Pool.map

来减少调整chink的大小
map