Python多线程threading join和守护线程setDeamon原理详解


Posted in Python onMarch 18, 2020

同一进程下的多个线程共享内存数据,多个线程之间没有主次关系,相互之间可以操作;cpu执行的都是线程,默认程序会开一个主线程;进程是程序以及和程序相关资源的集合;某些场景下我们可以使用多线程来达到提高程序执行效率的目的,下面就多线程的一些基础知识做简要说明

简单的多线程

import threading, time

def test1(x):
  time.sleep(5)
  print(x**x)

#下面定义两个线程调用test1这个函数,创建多线程使用如下语法,target后面跟函数名,args传递实参,实参需要以元组形式传递
start_time = time.time()
t1 = threading.Thread(target=test1, args=(5,))
t2 = threading.Thread(target=test1, args=(6,))
#启动多线程
t1.start()
t2.start()
end_time = time.time()
total_time = end_time - start_time
print("two Thread used %s time"%total_time) #由于使用多线程,t1 t2启动以后并不会等待期执行完程序才继续往后走,因为主程序就是主线程和t1 t2是并行执行的,主程序执行到此t1 t2并未运行完成

time.sleep(6)
#多线程启动数量比较多时可以使用for循环,多线程并行执行,打印的结果有可能不是按照启动顺序来打印的
for i in range(5):
  t3 = threading.Thread(target=test1, args=(i,))
  t3.start()
time.sleep(6)

主线程等待非主线程执行完毕才继续执行 join方法

#有些情况主线程需要子线程执行完毕后,有可能是将数据处理完毕后才执行接下来的主线程的东西
start_time1 = time.time()
tl = [] #将多线程的对象存起来,用于后面join方法
for i in range(5):
  t4 = threading.Thread(target=test1, args=(i,))
  t4.start()
  tl.append(t4)
for t in tl: #将多线程并发join,参加join的子线程执行完毕后才继续执行下面的主线程。
  t.join()
end_time1 = time.time()
total_time1 = end_time1 - start_time1
print(total_time1) #此次执行时间大约就是5s
#如果多个子线程一些join一些没有join主线程怎么处理???部分子线程join主线程会等join时间最长的子线程结束后才继续,未参与join的子线程仍然和主线程并行运行
t5 = threading.Thread(target=test1, args=(5,))
t6 = threading.Thread(target=test1, args=(6,))
t5.start()
t6.start()
t5_join_start_time = time.time()
t5.join()
time.sleep(10)
t5_join_end_time = time.time()
print("t5 join time is %s"%(t5_join_end_time - t5_join_start_time)) #实际耗时15s

守护线程 setDeamon

#守护进程,即主线程结束以后所有的其它线程也立即结束,不用等其它线程执行完毕;正常情况即使没加join主线程执行完毕当其它线程未执行完毕程序也不会退出,必须等待所有线程执行完毕程序才结束,类似主程序在末尾有默认的join
def test1(x):
  time.sleep(5)
  print("i an other Thread",x**x)

for i in range(5):
  t = threading.Thread(target=test1, args=(i,))
  t.setDaemon(True)
  t.start()

print("Main Thread is done") #整个程序结束,不会等待守护线程打印操作执行完毕就直接结束了

递归锁 Rlock

#递归锁,一个锁里面嵌套着锁,如果不使用递归锁会导致释放锁逻辑错误,整个程序就跑偏了;使用递归锁后程序会维护一个加锁 解锁的数据结构,保证释放锁不会出问题
lock = threading.Lock()
def test2():
  lock.acquire()
  print("this is test2")
  lock.release()

def test3():
  lock.acquire()
  print("this is test3")
  lock.release()

def test4():
  lock.acquire()
  test2()
  print("this is test4")
  test3()
  lock.release()

rlock_test = threading.Thread(target=test4)
rlock_test.start()

while threading.active_count() != 1:
  print("current thread count is",threading.active_count()) #整个程序一直在打印有两个线程,非主线程的锁嵌套出问题导致无法退出,整个程序卡死
  time.sleep(1)

将lock = threading.Lock()修改为lock = threading.RLock()整个程序就能正常结束;正常结束的输出如下

this is test2
this is test4
current thread count is 2
this is test3

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python文件和目录操作方法大全(含实例)
Mar 12 Python
python网络编程之TCP通信实例和socketserver框架使用例子
Apr 25 Python
python3实现读取chrome浏览器cookie
Jun 19 Python
Python实现注册登录系统
Aug 08 Python
python交互式图形编程实例(二)
Nov 17 Python
Python Cookie 读取和保存方法
Dec 28 Python
使用pycharm设置控制台不换行的操作方法
Jan 19 Python
Python pandas自定义函数的使用方法示例
Nov 20 Python
python路径的写法及目录的获取方式
Dec 26 Python
pycharm第三方库安装失败的问题及解决经验分享
May 09 Python
python/golang实现循环链表的示例代码
Sep 14 Python
如何使用PyCharm及常用配置详解
Jun 03 Python
Python semaphore evevt生产者消费者模型原理解析
Mar 18 #Python
Python中remove漏删和索引越界问题的解决
Mar 18 #Python
Python集成开发工具Pycharm的安装和使用详解
Mar 18 #Python
Python3监控windows,linux系统的CPU、硬盘、内存使用率和各个端口的开启情况详细代码实例
Mar 18 #Python
PyTorch加载自己的数据集实例详解
Mar 18 #Python
Python进程间通信multiprocess代码实例
Mar 18 #Python
python实现超级玛丽游戏
Mar 18 #Python
You might like
CodeIgniter配置之SESSION用法实例分析
2016/01/19 PHP
Windows下PHP开发环境搭建教程(Apache+PHP+MySQL)
2016/06/13 PHP
PHP new static 和 new self详解
2017/02/19 PHP
PHP7 windows支持
2021/03/09 PHP
Avengerls vs KG BO3 第二场2.18
2021/03/10 DOTA
select组合框option的捕捉实例代码
2008/09/30 Javascript
详细讲解JS节点知识
2010/01/31 Javascript
三种检测iPhone/iPad设备方向的方法
2014/04/23 Javascript
js阻止浏览器默认行为的简单实例
2016/05/15 Javascript
Jquery Easyui验证组件ValidateBox使用详解(20)
2016/12/18 Javascript
ExtJs的Ext.Ajax.request实现waitMsg等待提示效果
2017/06/14 Javascript
Vue Socket.io源码解读
2018/02/07 Javascript
node.js环境搭建图文详解
2018/09/19 Javascript
用Object.prototype.toString.call(obj)检测对象类型原因分析
2018/10/11 Javascript
使用 Vue cli 3.0 构建自定义组件库的方法
2019/04/30 Javascript
javascript实现图片轮播代码
2019/07/09 Javascript
Vue.js页面中有多个input搜索框如何实现防抖操作
2019/11/04 Javascript
vue 递归组件的简单使用示例
2021/01/14 Vue.js
[01:04:14]VP vs TNC 2018国际邀请赛小组赛BO2 第二场 8.17
2018/08/20 DOTA
Python中统计函数运行耗时的方法
2015/05/05 Python
一篇文章入门Python生态系统(Python新手入门指导)
2015/12/11 Python
Python中的列表生成式与生成器学习教程
2016/03/13 Python
Linux下通过python访问MySQL、Oracle、SQL Server数据库的方法
2016/04/23 Python
详解Django中间件执行顺序
2018/07/16 Python
Python爬虫之正则表达式基本用法实例分析
2018/08/08 Python
Django实现发送邮件功能
2019/07/18 Python
Python小程序 控制鼠标循环点击代码实例
2019/10/08 Python
TensorFlow基本的常量、变量和运算操作详解
2020/02/03 Python
浅谈python 调用open()打开文件时路径出错的原因
2020/06/05 Python
Python collections.defaultdict模块用法详解
2020/06/18 Python
python文件编写好后如何实践
2020/07/07 Python
零基础学Python之前需要学c语言吗
2020/07/21 Python
集团公司总经理岗位职责
2013/12/20 职场文书
个人投资合作协议书
2014/10/12 职场文书
党的群众路线教育实践活动个人整改措施范文
2014/11/04 职场文书
go语言中fallthrough的用法说明
2021/05/06 Golang