How to wait until only the first thread is finished in Python

Tan*_*n六四 15 python multithreading

The requirement is to start five threads, and wait only in the fastest thread. All five threads went to look for the same data 5 directions, and one is enough to continue the control flow.

Actually, I need to wait for the first two threads to return, to verify against each other. But I guess if I know how to wait for the fastest. I can figure out how to wait for the second-fastest.

很多人都在谈论join(timeout),但你事先并不知道哪一个要等(哪一个join提前申请).

Dun*_*can 16

使用队列:完成后每个线程将结果放在队列上,然后您只需要读取适当数量的结果并忽略其余部分:

#!python3.3
import queue    # For Python 2.x use 'import Queue as queue'
import threading, time, random

def func(id, result_queue):
    print("Thread", id)
    time.sleep(random.random() * 5)
    result_queue.put((id, 'done'))

def main():
    q = queue.Queue()
    threads = [ threading.Thread(target=func, args=(i, q)) for i in range(5) ]
    for th in threads:
        th.daemon = True
        th.start()

    result1 = q.get()
    result2 = q.get()

    print("Second result: {}".format(result2))

if __name__=='__main__':
    main()
Run Code Online (Sandbox Code Playgroud)

文档Queue.get()(没有参数,相当于Queue.get(True, None):

Queue.get([block [,timeout]])

从队列中删除并返回一个项目.如果可选的args块为true且timeout为None(默认值),则在必要时阻止,直到某个项可用为止.如果timeout是一个正数,它会阻止最多超时秒,如果在该时间内没有可用的项,则会引发Empty异常.否则(块为假),如果一个项立即可用则返回一个项,否则引发Empty异常(在这种情况下忽略超时).

  • @Michael,`q.get()`的默认值是做一个阻塞get,所以不会抛出异常而是阻塞主线程,直到有结果可用. (3认同)
  • 如果在执行 `q.get()` 时队列为空,这不会引发 `Empty` 异常吗? (2认同)

wil*_*art 5

如果您的线程中有某种处理循环,以下代码将在使用threading.Event()终止时终止它们:

def my_thread(stop_event):
    while not stop_event.is_set():
        # do stuff in a loop

        # some check if stuff is complete
        if stuff_complete:
            stop_event.set()
            break

def run_threads():
    # create a thread event
    a_stop_event = threading.Event()

    # spawn the threads
    for x in range(5):
        t = threading.Thread(target=my_thread, args=[a_stop_event])
        t.start()

    while not a_stop_event.is_set():
        # wait for an event
        time.sleep(0.1)

    print "At least one thread is done"
Run Code Online (Sandbox Code Playgroud)

如果您的流程“便宜”或单个请求-响应类型线程(例如异步 HTTP 请求),那么Duncan 的回答是一个很好的方法。


Lud*_*udo 2

您可以为此使用事件。请参阅http://docs.python.org/2/library/threading.html#event-objects 这个想法是工作线程在完成时引发一个事件。主线程在继续之前等待此事件。工作线程可以设置一个(互斥的)变量来通过事件来标识自己。