join() 在 Python 线程中有什么用?

新手上路,请多包涵

我正在研究 python 线程并遇到了 join()

作者告诉我,如果线程处于守护进程模式,那么我需要使用 join() 以便线程可以在主线程终止之前自行完成。

但我也看到他使用 t.join() 尽管 t 不是 daemon

示例代码是这样的:

 import threading
import time
import logging

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

def daemon():
    logging.debug('Starting')
    time.sleep(2)
    logging.debug('Exiting')

d = threading.Thread(name='daemon', target=daemon)
d.setDaemon(True)

def non_daemon():
    logging.debug('Starting')
    logging.debug('Exiting')

t = threading.Thread(name='non-daemon', target=non_daemon)

d.start()
t.start()

d.join()
t.join()

我不知道 t.join() 的用途是什么,因为它不是守护进程,即使删除它我也看不到任何变化

原文由 user192362127 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 434
2 个回答

一个有点笨拙的 ascii-art 来演示该机制: join() 大概是由主线程调用的。它也可以由另一个线程调用,但会不必要地使图表复杂化。

join 调用应该放在主线程的轨道上,但是为了表达线程关系并尽可能简单,我选择放在子线程中。

 without join:
+---+---+------------------                     main-thread
    |   |
    |   +...........                            child-thread(short)
    +..................................         child-thread(long)

with join
+---+---+------------------***********+###      main-thread
    |   |                             |
    |   +...........join()            |         child-thread(short)
    +......................join()......         child-thread(long)

with join and daemon thread
+-+--+---+------------------***********+###     parent-thread
  |  |   |                             |
  |  |   +...........join()            |        child-thread(short)
  |  +......................join()......        child-thread(long)
  +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,     child-thread(long + daemonized)

'-' main-thread/parent-thread/main-program execution
'.' child-thread execution
'#' optional parent-thread execution after join()-blocked parent-thread could
    continue
'*' main-thread 'sleeping' in join-method, waiting for child-thread to finish
',' daemonized thread - 'ignores' lifetime of other threads;
    terminates when main-programs exits; is normally meant for
    join-independent tasks

所以你看不到任何变化的原因是因为你的主线程在你的 join 之后什么都不做。您可以说 join (仅)与主线程的执行流程相关。

例如,如果您想并发下载一堆页面以将它们连接成一个大页面,您可以使用线程开始并发下载,但需要等到最后一个页面/线程完成后再开始组装单个页面出许多。那就是你使用 join() 的时候。

原文由 Don Question 发布,翻译遵循 CC BY-SA 4.0 许可协议

直接来自 文档

join([timeout]) 等待线程终止。这会阻塞调用线程,直到其 join() 方法被调用的线程终止(正常终止或通过未处理的异常终止)或直到发生可选的超时。

这意味着产生 td 的主线程等待 t 完成直到它完成。

根据您的程序使用的逻辑,您可能希望在主线程继续之前等到线程完成。

同样来自文档:

线程可以被标记为“守护线程”。这个标志的意义在于,当只剩下守护线程时,整个Python程序就退出了。

一个简单的例子,假设我们有这个:

 def non_daemon():
    time.sleep(5)
    print 'Test non-daemon'

t = threading.Thread(name='non-daemon', target=non_daemon)

t.start()

最后是:

 print 'Test one'
t.join()
print 'Test two'

这将输出:

 Test one
Test non-daemon
Test two

这里主线程显式等待 t 线程完成,直到它调用 print 第二次。

或者,如果我们有这个:

 print 'Test one'
print 'Test two'
t.join()

我们将得到这个输出:

 Test one
Test two
Test non-daemon

在这里,我们在主线程中完成工作,然后等待 t 线程完成。在这种情况下,我们甚至可以删除显式连接 t.join() 并且程序将隐式等待 t 完成。

原文由 dmg 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题