簡體   English   中英

如何使用 multiprocessing.Pool 判斷 apply_async 函數是否已啟動或仍在隊列中

[英]How to tell if an apply_async function has started or if it's still in the queue with multiprocessing.Pool

我正在使用 python 的 multiprocessing.Pool 和 apply_async 來調用一堆函數。

如何判斷函數是否已由池成員開始處理,或者它是否處於隊列中?

例如:

import multiprocessing
import time

def func(t):
    #take some time processing
    print 'func({}) started'.format(t)
    time.sleep(t)

pool = multiprocessing.Pool()

results = [pool.apply_async(func, [t]) for t in [100]*50] #adds 50 func calls to the queue

對於results每個AsyncResult ,您可以調用ready()get(0)以查看 func 是否已完成運行。 但是你怎么知道 func 是否啟動了但還沒有完成呢?

即對於給定的 AsyncResult 對象(即給定的結果元素),有沒有辦法查看該函數是否已被調用,或者它是否位於池的隊列中?

首先,從結果列表中刪除已完成的作業

    results = [r for r in results if not r.ready()]

待處理的進程數是結果列表的長度:

    pending = len(results)

待處理但未啟動的數量是待處理的總數 - pool_size

    not_started = pending - pool_size

如果 Pool 是使用默認參數創建的,則 pool_size 將是 multiprocessing.cpu_count()

更新:在最初誤解了這個問題之后,這里有一種方法可以做 OP 所問的問題。

我懷疑這個功能可以添加到 Pool 類中而不會有太多麻煩,因為 AsyncResult 是由帶有隊列的 Pool 實現的。 該隊列也可以在內部使用以指示是否已啟動。

但是這里有一種使用 Pool 和 Pipe 來實現的方法。 注意:這在 Python 2.x 中不起作用——不知道為什么。 在 Python 3.8 中測試。

import multiprocessing
import time
import os

def worker_function(pipe):
    pipe.send('started')
    print('[{}] started pipe={}'.format(os.getpid(), pipe))
    time.sleep(3)
    pipe.close()

def test():
    pool = multiprocessing.Pool(processes=2)
    print('[{}] pool={}'.format(os.getpid(), pool))

    workers = []

    for x in range(1, 4):
        parent, child = multiprocessing.Pipe()
        pool.apply_async(worker_function, (child,))
        worker = {'name': 'worker{}'.format(x), 'pipe': parent, 'started': False}
        workers.append(worker)

    pool.close()

    while True:
        for worker in workers:
            if worker.get('started'):
                continue
            pipe = worker.get('pipe')
            if pipe.poll(0.1):
                message = pipe.recv()
                print('[{}] {} says {}'.format(os.getpid(), worker.get('name'), message))
                worker['started'] = True
                pipe.close()
        count_in_queue = len(workers)
        for worker in workers:
            if worker.get('started'):
                count_in_queue -= 1
        print('[{}] count_in_queue = {}'.format(os.getpid(), count_in_queue))
        if not count_in_queue:
            break
        time.sleep(0.5)

    pool.join()

if __name__ == '__main__':
    test()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM