【问题标题】:Python threading - do something while join()Python 线程 - 在 join() 时做一些事情
【发布时间】:2016-05-24 19:06:56
【问题描述】:

Python 2.6.6

我有一个要执行的线程列表,主代码将等待 (Threading.join()) 直到它们全部完成。

>>> for thread in threadList:
...     thread.start()
>>> for t in threadList:
...     t.join()

有没有办法在主代码等待线程结束时打印诸如“正在运行...”之类的消息?

我想一秒又一秒地打印相同的东西(“正在运行...”),直到线程全部完成。

谢谢。


已解决

实施的解决方案:

>>> for thread in threadList:
...     thread.start()
>>> string = "running"
>>> while any(t.is_alive() for t in threadList):
...    sys.stdout.write("\r%s" % string)
...    sys.stdout.flush()
...    string = string + "."                     #this may not be the best way
...    time.sleep(0.5)

在我的情况下,“time.sleep(0.5)”的额外时间不是问题,尽管它不是最推荐的。

这会生成输出:

running........

“running”之后的点将一个接一个地打印在同一行,同时还有任何线程处于活动状态。果然如我所料!

基于@Manuel Jacob 和@Alex Hall 的回答。

【问题讨论】:

    标签: python multithreading


    【解决方案1】:

    Thread.join() 被设计为阻塞。您可以定期调用 Thread.is_alive(),而不是使用 Thread.join()。

    您的示例已改编:

    for thread in threadList:
        thread.start()
    while any(thread.is_alive() for thread in threadList):
        print('running...')
        time.sleep(1)
    

    正如 cmets 中所指出的,当最后一个线程在睡眠期间完成时,这可能会导致最多一秒的额外延迟。

    【讨论】:

    • 这将导致最多一秒钟的额外等待。
    • 谢谢,曼努埃尔·雅各布!它工作得很好。我将更新问题以显示我的结果。
    【解决方案2】:
    from time import sleep
    from threading import Thread
    
    threadList = [Thread(target=lambda: sleep(3)), Thread(target=lambda: sleep(5))]
    
    for thread in threadList:
        thread.start()
    
    def check_running():
        while True:
            alive = sum(thread.is_alive() for thread in threadList)
            if not alive:
                break
            print '%s threads still running...' % alive
            sleep(1)
    
    Thread(target=check_running).start()
    
    for t in threadList:
        t.join()
    

    输出:

    2 threads still running...
    2 threads still running...
    2 threads still running...
    1 threads still running...
    1 threads still running...
    

    或者:

    from time import sleep
    from threading import Thread
    
    threadList = [Thread(target=lambda: sleep(3), name='Alice'), Thread(target=lambda: sleep(5), name='Bob')]
    
    for thread in threadList:
        thread.start()
    
    for t in threadList:
        while True:
            t.join(timeout=1)
            if not t.is_alive():
                break
            print('%s is still running...' % t.name)
    

    输出:

    Alice is still running...
    Alice is still running...
    Bob is still running...
    

    【讨论】:

    • 你也应该在最后加入check_running 线程
    • @njzk2 为什么?这将导致程序需要更长的时间才能完成,我们不在乎。
    • 只是为了确保一切都已关闭,您可以将连接循环替换为与监控线程的单个连接
    • @njzk2 如果监视器线程有可能出现错误并且不会终止,我宁愿让它占用少量资源而不是让程序永远卡住。也会造成不必要的等待。
    • 谢谢,亚历克斯霍尔!您的第二个解决方案(“Alternavely”)最适合该问题。我已经实现了@Manuel Jacob 的解决方案,因为其他人更容易理解,我需要这种简单性,以便我的合作伙伴(不是 Python 程序员)能够为代码提供支持。
    猜你喜欢
    • 2011-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多