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的Django框架来制作一个RSS阅读器
Jul 22 Python
Python实现按学生年龄排序的实际问题详解
Aug 29 Python
Python利用matplotlib做图中图及次坐标轴的实例
Jul 08 Python
python Tcp协议发送和接收信息的例子
Jul 22 Python
Python中的sys.stdout.write实现打印刷新功能
Feb 21 Python
Python代码中如何读取键盘录入的值
May 27 Python
在pytorch中动态调整优化器的学习率方式
Jun 24 Python
Python3合并两个有序数组代码实例
Aug 11 Python
爬虫代理的cookie如何生成运行
Sep 22 Python
python cookie反爬处理的实现
Nov 01 Python
详解Python中@staticmethod和@classmethod区别及使用示例代码
Dec 14 Python
只用20行Python代码实现屏幕录制功能
Jun 02 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
基于php实现随机合并数组并排序(原排序)
2015/11/26 PHP
PHP常用字符串函数小结(推荐)
2018/08/05 PHP
jquery中常用的SET和GET
2009/01/13 Javascript
javascript 获取select下拉列表值的代码
2009/09/07 Javascript
javascript中substr,substring,slice.splice的区别说明
2010/11/25 Javascript
你知道setTimeout是如何运行的吗?
2016/08/16 Javascript
谈谈JavaScript的New关键字
2016/08/26 Javascript
JS实现的A*寻路算法详解
2018/12/14 Javascript
Node.js一行代码实现静态文件服务器的方法步骤
2019/05/07 Javascript
JS实现公告上线滚动效果
2021/01/10 Javascript
vue+flask实现视频合成功能(拖拽上传)
2021/03/04 Vue.js
[01:21]DOTA2 新英雄 森海飞霞
2020/12/18 DOTA
Python 分析Nginx访问日志并保存到MySQL数据库实例
2014/03/13 Python
简单理解Python中基于生成器的状态机
2015/04/13 Python
python中使用序列的方法
2015/08/03 Python
实例讲解Python中函数的调用与定义
2016/03/14 Python
使用python获取电脑的磁盘信息方法
2018/11/01 Python
Django获取应用下的所有models的例子
2019/08/30 Python
python PIL模块的基本使用
2020/09/29 Python
Python爬虫自动化爬取b站实时弹幕实例方法
2021/01/26 Python
Python3爬虫ChromeDriver的安装实例
2021/02/06 Python
真正了解CSS3背景下的@font face规则
2017/05/04 HTML / CSS
html5触摸事件判断滑动方向的实现
2018/06/05 HTML / CSS
洛杉矶生活休闲而精致的基础品牌:Mika Jaymes
2018/01/07 全球购物
Fossil美国官网:化石手表、手袋、首饰及配饰
2019/02/17 全球购物
捷克家具销售网站:SCONTO Nábytek
2020/01/02 全球购物
香港艺人陈冠希创办的潮流品牌:JUICESTORE
2021/03/04 全球购物
索引覆盖(Index Covering)查询含义
2012/02/18 面试题
小学校长竞聘演讲稿
2014/05/16 职场文书
2015年妇产科工作总结
2015/05/18 职场文书
小学生优秀作文范文(六篇)
2019/07/10 职场文书
如何理解及使用Python闭包
2021/06/01 Python
详解Spring Boot使用系统参数表提升系统的灵活性
2021/06/30 Java/Android
MySQL系列之二 多实例配置
2021/07/02 MySQL
python如何查找列表中元素的位置
2022/05/30 Python
新的CSS 伪类函数 :is() 和 :where()示例详解
2022/08/05 HTML / CSS