Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/323.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 确定线程池何时完成队列处理_Python_Queue_Threadpool_Multiprocessing - Fatal编程技术网

Python 确定线程池何时完成队列处理

Python 确定线程池何时完成队列处理,python,queue,threadpool,multiprocessing,Python,Queue,Threadpool,Multiprocessing,我正在尝试实现一个线程池,它使用ThreadPool和queue处理任务队列。它从一个初始任务队列开始,然后每个任务还可以将其他任务推送到任务队列上。问题是,在队列为空且线程池完成处理之前,我不知道如何阻止,但仍然会检查队列并向推送到队列上的线程池提交任何新任务。我不能简单地调用ThreadPool.join(),因为我需要为新任务打开池 例如: from multiprocessing.pool import ThreadPool from Queue import Queue from ra

我正在尝试实现一个线程池,它使用
ThreadPool
queue
处理任务队列。它从一个初始任务队列开始,然后每个任务还可以将其他任务推送到任务队列上。问题是,在队列为空且线程池完成处理之前,我不知道如何阻止,但仍然会检查队列并向推送到队列上的线程池提交任何新任务。我不能简单地调用
ThreadPool.join()
,因为我需要为新任务打开池

例如:

from multiprocessing.pool import ThreadPool
from Queue import Queue
from random import random
import time
import threading

queue = Queue()
pool = ThreadPool()
stdout_lock = threading.Lock()

def foobar_task():
    with stdout_lock: print "task called" 
    if random() > .25:
        with stdout_lock: print "task appended to queue"
        queue.append(foobar_task)
    time.sleep(1)

# set up initial queue
for n in range(5):
    queue.put(foobar_task)

# run the thread pool
while not queue.empty():
    task = queue.get() 
    pool.apply_async(task)

with stdout_lock: print "pool is closed"
pool.close()
pool.join()
这将产生:

pool is closed
task called
task appended to queue
task called
task appended to queue
task called
task appended to queue
task called
task appended to queue
task called
task appended to queue
这将在foobar_任务附加到队列之前退出while循环,因此附加的任务永远不会提交到线程池。我找不到任何方法来确定线程池是否仍有任何活动的工作线程。我尝试了以下方法:

while not queue.empty() or any(worker.is_alive() for worker in pool._pool):
    if not queue.empty():
        task = queue.get() 
        pool.apply_async(task)
    else:   
        with stdout_lock: print "waiting for worker threads to complete..."
        time.sleep(1)
但似乎
worker.is\u alive()
总是返回true,因此这进入了一个无限循环

有更好的方法吗

  • 在处理每个任务后调用
  • 然后可以调用阻止主线程,直到所有 任务已经完成
  • 要终止工作线程,请在队列中放置哨兵(例如,
    None
    ), 当它接收到哨兵时,让
    foobar_任务
    中断
    while循环
  • 我认为使用
    threading.Thread
    s比使用
    ThreadPool
    更容易实现这一点

  • import random
    import time
    import threading
    import logging
    import Queue
    
    logger=logging.getLogger(__name__)
    logging.basicConfig(level=logging.DEBUG)
    
    sentinel=None
    queue = Queue.Queue()
    num_threads = 5
    
    def foobar_task(queue):
        while True:
            n = queue.get()
            logger.info('task called: {n}'.format(n=n))
            if n is sentinel: break
            n=random.random()
            if n > .25:
                logger.info("task appended to queue")
                queue.put(n)
            queue.task_done()
    
    # set up initial queue
    for i in range(num_threads):
        queue.put(i)
    
    threads=[threading.Thread(target=foobar_task,args=(queue,))
             for n in range(num_threads)]
    for t in threads:
        t.start()
    
    queue.join()
    for i in range(num_threads):
        queue.put(sentinel)
    
    for t in threads:
        t.join()
    logger.info("threads are closed")