Python:在while循环中使用join()的线程

时间:2011-10-29 08:21:58

标签: python join while-loop block python-multithreading

我希望我的while循环最多可以阻止它在for循环中创建的所有线程。但是,以下代码将逐个被线程阻塞。我怎样才能实现目标?感谢。

threads = []
while True:
    for 3:
        newThread = threading.Thread(..)
        threads.append(newThread)
        newThread.start()
        newThread.join(5)

3 个答案:

答案 0 :(得分:3)

您需要在Python中使用条件变量(threading.Condition)。它允许等待谓词变为真。在您的情况下,谓词是all threads have finished work or time out exceeded。这是一个代码,它创建十个线程并等待它们完成5秒超时。详细日志可以帮助您:

import threading
import time
import logging


logging.basicConfig(
    format='%(threadName)s:%(message)s',
    level=logging.DEBUG,
)


NUM_OF_THREADS = 10
TIMEOUT = 5


def sleeping_thread(delay, cond):
    logging.debug("Hi, I'm going to delay by %d sec." % delay)
    time.sleep(delay)
    logging.debug("I was sleeping for %d sec." % delay)
    cond.acquire()
    logging.debug("Calling notify().")
    cond.notify()
    cond.release()


def create_sleeping_thread(delay, cond):
    return threading.Thread(target=sleeping_thread,
                            args=(delay, cond))


if __name__ == '__main__':
    cond = threading.Condition(threading.Lock())
    cond.acquire()

    working_counter = NUM_OF_THREADS
    for i in xrange(NUM_OF_THREADS):
        t = create_sleeping_thread(i, cond)
        t.start()

    start_time = time.time()
    while working_counter > 0 and (time.time() - start_time < TIMEOUT):
        cond.wait()
        working_counter -= 1
        logging.debug('%d workers still working', working_counter)
    cond.release()
    logging.debug('Finish waiting for threads (%d workers still working)',
                 working_counter)

comp.programming.threads FAQ的更多信息。

答案 1 :(得分:1)

要做的一件事是启动所有线程,然后迭代数组并加入。但我想,这仍然会等待总共5 *线程计数秒。或者,您可以创建一个额外的线程,只是无限期地等待您的线程。然后在你的主线程中你可以等待额外的线程5秒钟。

答案 2 :(得分:0)

你是否每隔5秒尝试生成一个线程,除非其中一个已经运行的线程结束,你希望更快地生成一个新线程?如果是这样,您可以使用threading.Event在工作线程结束时发出信号,并使用event.wait(timeout)阻止该事件最多5秒:

import threading
import time
import logging

logger=logging.getLogger(__name__)

logging.basicConfig(level=logging.DEBUG,
                    format='%(asctime)s: %(message)s',
                    datefmt='%H:%M:%S')

def foo_event(n,e):
    time.sleep(n)
    name=threading.current_thread().name
    logger.info('{n}: setting event'.format(n=name))
    e.set()

def main():
    e=threading.Event()
    threads=[]
    N=5
    for i in range(3):
        t=threading.Thread(target=foo_event,args=(N+1,e,),name='worker-{i}'.format(i=i))
        threads.append(t)
        t.daemon=True
        t.start()
        logger.info('entering wait')
        e.wait(N)
        logger.info('exit wait')
        e.clear()

main()

产量

05:06:34: entering wait
05:06:39: exit wait                 <-- Wait 5 seconds
05:06:39: entering wait
05:06:40: worker-0: setting event   
05:06:40: exit wait                 <-- Wait <5 seconds
05:06:40: entering wait
05:06:45: worker-1: setting event
05:06:45: exit wait                 <-- Wait 5 seconds