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,另博客账号也是本人微信号。
版权声明:此文是博主业余爱好所写,文章或有错误与不足之处,欢迎留言指正建议、共同探讨!另此文为博主原创,未经博主同意不得转载,否则保留追究法律责任的权利。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 周边上新:园子的第一款马克杯温暖上架
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
· 使用C#创建一个MCP客户端