1. 程式人生 > 程式設計 >python執行緒join方法原理解析

python執行緒join方法原理解析

這篇文章主要介紹了python執行緒join方法原理解析,文中通過示例程式碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下

幾個事實

1 python 預設引數建立執行緒後,不管主執行緒是否執行完畢,都會等待子執行緒執行完畢才一起退出,有無join結果一樣

2 如果建立執行緒,並且設定了daemon為true,即thread.setDaemon(True),則主執行緒執行完畢後自動退出,不會等待子執行緒的執行結果。而且隨著主執行緒退出,子執行緒也消亡。

3 join方法的作用是阻塞,等待子執行緒結束,join方法有一個引數是timeout,即如果主執行緒等待timeout,子執行緒還沒有結束,則主執行緒強制結束子執行緒。

4 如果執行緒daemon屬性為False, 則join裡的timeout引數無效。主執行緒會一直等待子執行緒結束。

5 如果執行緒daemon屬性為True, 則join裡的timeout引數是有效的, 主執行緒會等待timeout時間後,結束子執行緒。此處有一個坑,即如果同時有N個子執行緒join(timeout),那麼實際上主執行緒會等待的超時時間最長為 N * timeout, 因為每個子執行緒的超時開始時刻是上一個子執行緒超時結束的時刻。

測試程式碼

import threading,time

def func():
  print "start thread time: ",time.strftime('%H:%M:%S')
  time.sleep(3)
  print "stop thread time: ",time.strftime('%H:%M:%S')

thread_list = []
for i in range(3):
  t1 = threading.Thread(target=func)
  #t1.setDaemon(True)

  thread_list.append(t1)

for r in thread_list:
  r.start()

for t in thread_list:
  #t.join(1)
  t.join()
print "stop main thread"

###子執行緒如果設定了t.join(timeout),則根據timeout的不同,結果會不同,前提是設定了setDaemon(True),否則join的timeout是沒效的

#設定了setDaemon(True),但是沒設定t.join()的執行結果:
#start thread time: 17:25:29
#start thread time: 17:25:29
#start thread time: 17:25:29
#stop main thread

#加了t1.setDaemon(True),並且設定了超時時間t.join(1)的執行結果:
#start thread time: 17:12:24
#start thread time: 17:12:24
#start thread time: 17:12:24
#stop main thread

#沒加t1.setDaemon(True),並且設定了超時時間t.join(1)的執行結果,不過因為setDaemon的引數不是True所以就算設定了超時時間也沒用:
#start thread time: 17:13:28
#start thread time: 17:13:28
#start thread time: 17:13:28
#stop main thread
#stop thread time:  17:13:31
#stop thread time:  17:13:31
#stop thread time:  17:13:31

#沒加t1.setDaemon(True),但是設定了t.join(),沒有超時時間的阻塞的執行結果:
#start thread time: 17:16:12
#start thread time: 17:16:12
#start thread time: 17:16:12
#stop thread time:  17:16:15
#stop thread time:  17:16:15
#stop thread time:  17:16:15
#stop main thread 

#即沒有設定setDaemon(True),也沒有設定join()的執行結果:
#start thread time: 17:22:25
#start thread time: 17:22:25
#start thread time: 17:22:25
#stop main thread
#stop thread time:  17:22:28
#stop thread time:  17:22:28
#stop thread time:  17:22:28

總結:

如果想讓子程序正常的執行結束(子程序中所有的內容都運行了),則如果設定join(timeout)的話,前提是設定setDaemon(True),且setDaemon的引數為True,且join(timeout)的超時時間必須大於子程序執行所需的時間,不然沒等子程序執行結束就超時退出了或者直接設定join()不帶超時時間,也不用設定setDaemon(True)了

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。