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),此子菜鸟仓为守护线程,父线程退出,所有守护子线程立即结束
作者名称:Vrapile
联系方式:发送邮件Vrapile@163.com,另博客账号也是本人微信号。
版权声明:此文是博主业余爱好所写,文章或有错误与不足之处,欢迎留言指正建议、共同探讨!另此文为博主原创,未经博主同意不得转载,否则保留追究法律责任的权利。