join和daemon
下面僅以多進程為例:
知識點一:
當一個進程啟動之后,會默認產生一個主線程,因為線程是程序執行流的最小單元,當設置多線程時,主線程會創建多個子線程,在python中,默認情況下(其實就是setDaemon(False)),主線程執行完自己的任務以后,就退出了,此時子線程會繼續執行自己的任務,直到自己的任務結束,例子見下面一。
知識點二:
當我們使用setDaemon(True)方法,也就是設置子線程為守護線程時,主線程一旦執行結束,則全部線程全部被終止執行,可能出現的情況就是,子線程的任務還沒有完全執行結束,就被迫停止,例子見下面二。
知識點三:
此時join的作用就凸顯出來了,join所完成的工作就是線程同步,即主線程任務結束之后,進入阻塞狀態,一直等待其他的子線程執行結束之后,主線程再終止,例子見下面三。
知識點四:
join有一個timeout參數: 當設置守護線程時,含義是主線程對於子線程等待timeout的時間將會殺死該子線程,最后退出程序。所以說,如果有10個子線程,全部的等待時間就是每個timeout的累加和。簡單的來說,就是給每個子線程一個timeout的時間,讓他去執行,時間一到,不管任務有沒有完成,直接殺死。 沒有設置守護線程時,主線程將會等待timeout的累加和這樣的一段時間,時間一到,主線程結束,但是並沒有殺死子線程,子線程依然可以繼續執行,直到子線程全部結束,程序退出。
設置daemon:
import threading import time def run(): time.sleep(2) print('當前線程的名字是: ', threading.current_thread().name) time.sleep(2) if __name__ == '__main__': start_time = time.time() print('這是主線程:', threading.current_thread().name) thread_list = [] for i in range(5): t = threading.Thread(target=run) thread_list.append(t) for t in thread_list: t.setDaemon(True) t.start() print('主線程結束了!' , threading.current_thread().name) print('一共用時:', time.time()-start_time)
運行結果如下:
非常明顯的看到,主線程結束以后,子線程還沒有來得及執行,整個程序就退出了。
設置join
1 # join 2 import threading 3 import time 4 5 6 def run(): 7 time.sleep(2) 8 print('當前線程的名字是: ', threading.current_thread().name) 9 time.sleep(2) 10 11 12 if __name__ == '__main__': 13 14 start_time = time.time() 15 16 print('這是主線程:', threading.current_thread().name) 17 thread_list = [] 18 for i in range(5): 19 t = threading.Thread(target=run) 20 thread_list.append(t) 21 22 for t in thread_list: 23 t.setDaemon(True) 24 t.start() 25 26 for t in thread_list: 27 t.join() 28 29 print('主線程結束了!', threading.current_thread().name) 30 print('一共用時:', time.time() - start_time) 31 # https://www.cnblogs.com/kujiawei
運行結果如下:
可以看到,主線程一直等待全部的子線程結束之后,主線程自身才結束,程序退出。