Python线程的join和setDaemon探究

一、前言

  由于查阅资料众口不一,故决定自己写代码,来证实正确结果,此文根据一段代码,来探究Python的线程运行情况,读者可运行代码自己调试理解。

  系统环境Win10,运行环境Python3.6,运行工具Pycharm。

 

二、实现思路

  1.通过改变每个线程的sleep()时长,以及setDaemon()和join()的属性,来改变结果

  1.通过控制台打印时间和线程的结果变化来分析线程运行情况

 

三、源码设计

 1 import threading
 2 import time
 3 
 4 
 5 # 返回当前时间年月日+时分秒+毫秒
 6 def getcurrenttime():
 7     tt = time.time()
 8     local_time = time.localtime(tt)
 9     data_head = time.strftime("%Y-%m-%d %H:%M:%S", local_time)
10     data_secs = (tt - int(tt)) * 1000000
11     return "%s %06d" % (data_head, data_secs)
12 
13 
14 # 返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程
15 def getallthread():
16     return threading.enumerate()
17 
18 
19 def printmsg(puple):  # 打印结果
20     print("There is running %s %s %s %s" % puple)
21 
22 
23 def task0(tag):
24     while True:
25         printmsg((tag, getcurrenttime(), threading.current_thread().getName(), getallthread()))
26         time.sleep(1)
27 
28 
29 def task1(tag):
30     for i in range(2):
31         printmsg((tag, getcurrenttime(), threading.current_thread().getName(), ""))
32         time.sleep(5)
33 
34 
35 def task2(tag):
36     for i in range(2):
37         printmsg((tag, getcurrenttime(), threading.current_thread().getName(), ""))
38         time.sleep(3)
39 
40 
41 def threadsstart():
42     t0 = threading.Thread(target=task0, name="task0", args=(u'task0',))
43     # 默认继承父级属性:True父线程结束子线程立即结束;False子线程结束父线程才会退出
44     t0.setDaemon(True)
45     t0.start()
46 
47     t1 = threading.Thread(target=task1, name="task1", args=(u'task1',))
48     t1.setDaemon(False)
49     t1.start()
50     # 主线程等待最多7秒,等待过程后面子线程t2不会执行
51     t1.join(7)
52 
53     t2 = threading.Thread(target=task2, name="task2", args=(u'task2',))
54     t2.setDaemon(True)
55     t2.start()
56 
57 
58 if __name__ == '__main__':
59     threadsstart()
60     printmsg(("end00", getcurrenttime(), threading.current_thread().getName(), ""))

部分打印结果

 1 D:\Python\python.exe E:/Python/Demo/venv/thread_test/threading_test.py
 2 There is running task0 2018-11-29 16:28:52 600983 task0 [<_MainThread(MainThread, started 8904)>, <Thread(task0, started daemon 9024)>]
 3 There is running task1 2018-11-29 16:28:52 601979 task1 
 4 There is running task0 2018-11-29 16:28:53 602678 task0 [<_MainThread(MainThread, started 8904)>, <Thread(task0, started daemon 9024)>, <Thread(task1, started 2280)>]
 5 There is running task0 2018-11-29 16:28:54 603651 task0 [<_MainThread(MainThread, started 8904)>, <Thread(task0, started daemon 9024)>, <Thread(task1, started 2280)>]
 6 There is running task0 2018-11-29 16:28:55 604120 task0 [<_MainThread(MainThread, started 8904)>, <Thread(task0, started daemon 9024)>, <Thread(task1, started 2280)>]
 7 There is running task0 2018-11-29 16:28:56 604486 task0 [<_MainThread(MainThread, started 8904)>, <Thread(task0, started daemon 9024)>, <Thread(task1, started 2280)>]
 8 There is running task1 2018-11-29 16:28:57 603277 task1 
 9 There is running task0 2018-11-29 16:28:57 605237 task0 [<_MainThread(MainThread, started 8904)>, <Thread(task0, started daemon 9024)>, <Thread(task1, started 2280)>]
10 There is running task0 2018-11-29 16:28:58 606382 task0 [<_MainThread(MainThread, started 8904)>, <Thread(task0, started daemon 9024)>, <Thread(task1, started 2280)>]
11 There is running task2 2018-11-29 16:28:59 603960 task2 
12 There is running end00 2018-11-29 16:28:59 603960 MainThread 
13 There is running task0 2018-11-29 16:28:59 606956 task0 [<_MainThread(MainThread, stopped 8904)>, <Thread(task0, started daemon 9024)>, <Thread(task1, started 2280)>, <Thread(task2, started daemon 8028)>]
14 There is running task0 2018-11-29 16:29:00 607855 task0 [<_MainThread(MainThread, stopped 8904)>, <Thread(task0, started daemon 9024)>, <Thread(task1, started 2280)>, <Thread(task2, started daemon 8028)>]
15 There is running task0 2018-11-29 16:29:01 608642 task0 [<_MainThread(MainThread, stopped 8904)>, <Thread(task0, started daemon 9024)>, <Thread(task1, started 2280)>, <Thread(task2, started daemon 8028)>]
16 
17 Process finished with exit code 0

 

四、分析总结

  1.打印结果有时间秒数,有线程及属性,不断更改设置,查看不同的结果,总结如下:

  (a)join(time=60),父线程会在此线程最多阻塞60s,join后的线程不会运行,join前已经运行的线程不受影响

  (b)setDaemon(False),此子线程为非守护线程,所有非守护子线程结束,父线程才会退出

  (c)setDaemon(True),此子菜鸟仓为守护线程,父线程退出,所有守护子线程立即结束

 

posted @ 2018-11-29 16:49  Vrapile  阅读(267)  评论(0编辑  收藏  举报