浅谈python多线程和多线程变量共享问题介绍


Posted in Python onApril 17, 2020

1、demo

第一个代码是多线程的简单使用,编写了线程如何执行函数和类。

import threading
import time
class ClassName(threading.Thread):
	"""创建类,通过多线程执行"""
	def run(self):
		for i in range(5):
			print(i)
			time.sleep(1)

def sing():
	for i in range(1,11):
		print("唱歌第 %d 遍" % i)
		time.sleep(1)

def dance():
	for i in range(1,16):
		print("跳舞第 %d 遍" % i)
		time.sleep(1)

def main():
	t1 = threading.Thread(target = sing)
	t2 = threading.Thread(target = dance)
	t = ClassName()
	
	# 启动线程
	t1.start()
	t2.start()
	t.start()

	while True:
		length = len(threading.enumerate())
		print("正在运行的线程有 %s" %threading.enumerate())
	
		if length <= 1:
			break
		time.sleep(1)

if __name__ == '__main__':
	main()

执行结果可以看到函数 sing、dance和类在同时执行,执行效果太长就不方截图了

2、多线程共享变量

通过定义全局变量,然后再test1函数类部进行更改全局变量,test2打印全局变量。

import threading
import time

#定义全局变量
g_num = 0

def test1():
	"""函数test1对全局变量进行更改"""
	global g_num
	for i in range(1,10):
		g_num += 1

	print("--- test1 线程 g_num = %d--- " % g_num)

def test2():
	"""函数test2 打印全局变量"""
	print("--- test2 线程 g_num = %d--- " % g_num)

def main():
	t1 = threading.Thread(target=test1)
	t2 = threading.Thread(target=test2)

	# 启动线程
	t1.start()
	# 增加睡眠是为了保证优先执行函数test1
	time.sleep(1)
	t2.start()

	print("--- 主线程 g_num = %d--- " % g_num)

if __name__ == '__main__':
	main()

执行结果可以看出,在主线程和创建的两个线程中读取的是一样的值,既可以表明在多线程中变量共享

浅谈python多线程和多线程变量共享问题介绍

3、资源竞争

在多线程两个函数中同时更改一个变量时,由于cpu的计算能力,当修改参数的代码块无法一次性执行完成时,就会产生资源竞争

import threading
import time

# 定义全局变量
g_num = 0

def test1(num):
	"""函数test1对全局变量进行更改"""
	global g_num
	for i in range(num):
		g_num += 1

	print("test1 线程 g_num = %d---" % g_num)

def test2(num):
	"""函数test2对全局变量进行更改"""
	global g_num
	for i in range(num):
		g_num += 1

	print("tes2 线程 g_num = %d---" % g_num)

def main():
	t1 = threading.Thread(target=test1, args=(1000000, ))
	t2 = threading.Thread(target=test2, args=(1000000, ))

	t1.start()
	t2.start()

	time.sleep(1)
	print("主线程 g_num = %d---" % g_num)

if __name__ == '__main__':
	main()

可以先试试传递参数为100时,可以看到g_num = 200 这是因为函数代码可以一次性执行完成,当参数为1000000时代码无法一次性执行完成,g_num!= 2000000

浅谈python多线程和多线程变量共享问题介绍

4、互斥锁

互斥锁可以解决资源竞争的问题,原理很简单,通过对代码块上锁,保证该代码执行完成前,其它代码无法进行修改。执行完成后解锁,其它代码就可以执行了。

import threading
import time

# 创建变量
g_num = 0
# 创建锁默认为开锁状态
mutex = threading.Lock()

def test1(num):
	global g_num
	for i in range(num):
		# 上锁
		mutex.acquire()
		g_num += 1
		# 解锁
		mutex.release()
	print("--- test1 线程 g_num = %d---" % g_num)

def test2(num):
	global g_num
	for i in range(num):
		# 上锁
		mutex.acquire()
		g_num += 1
		# 解锁
		mutex.release()

	print("--- test2 线程 g_num = %d---" % g_num)

def main():
	t1 = threading.Thread(target=test1, args=(1000000, ))
	t2 = threading.Thread(target=test2, args=(1000000, ))

	t1.start()
	t2.start()

	time.sleep(1)
	print("--- 主线程 g_num = %d---" % g_num)

if __name__ == '__main__':
	main()

可以看到加了锁之后,代码执行不会出现资源竞争,结果也是正常的。互斥锁,上锁的代码越少越好。

浅谈python多线程和多线程变量共享问题介绍

5、死锁

当出现多个锁时,就可能会产生死锁这个情况。当关闭一个锁时,这个锁已经为关闭状态的话,程序就会阻塞。就如同下面这个代码中。函数test1关闭mutexB锁时,函数test2提前将其关闭了,未进行解锁,程序就会一直阻塞。

import threading
import time

# 创建两个锁A, B
mutexA = threading.Lock()
mutexB = threading.Lock()

def test1():
	# 对muctexA上锁
	mutexA.acquire()

	# mutexA上锁后,延时1秒,等待mutexB上锁
	print("test1 ---do1---up---")
	time.sleep(1)
	# 此时会堵塞,因为mutexB已经上锁
	mutexB.acquire()
	print("test1 ---do1---down---")
	mutexB.release()

	# 对mutexA解锁
	mutexA.release()

def test2():
	# 对muctexB上锁
	mutexB.acquire()

	# mutexB上锁后,延时1秒,等待mutexA上锁
	print("test2 ---do1---up---")
	time.sleep(1)
	# 此时会堵塞,因为mutexB已经上锁
	mutexA.acquire()
	print("test2 ---do1---down---")
	mutexA.release()

	# 对mutexA解锁
	mutexB.release()

def main():
	t1 = threading.Thread(target=test1)
	t2 = threading.Thread(target=test2)

	t1.start()
	t2.start()


if __name__ == '__main__':
	main()

代码执行效果可以看到程序会一直阻塞
解决方法
1、在程序编写时,就需要注意避免死锁
2、可以参考银行家算法

浅谈python多线程和多线程变量共享问题介绍

到此这篇关于浅谈python多线程和多线程变量共享问题介绍的文章就介绍到这了,更多相关python 多线程变量共享内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
python中 ? : 三元表达式的使用介绍
Oct 09 Python
Python实现简单的可逆加密程序实例
Mar 05 Python
用Python进行行为驱动开发的入门教程
Apr 23 Python
Python使用matplotlib实现绘制自定义图形功能示例
Jan 18 Python
python的Crypto模块实现AES加密实例代码
Jan 22 Python
python实现一个简单的ping工具方法
Jan 31 Python
python根据文章标题内容自动生成摘要的实例
Feb 21 Python
浅谈Python3 numpy.ptp()最大值与最小值的差
Aug 24 Python
Python 中的 import 机制之实现远程导入模块
Oct 29 Python
Python实现线性判别分析(LDA)的MATLAB方式
Dec 09 Python
使用jupyter notebook将文件保存为Markdown,HTML等文件格式
Apr 14 Python
基于python制作简易版学生信息管理系统
Apr 20 Python
使用Matplotlib绘制不同颜色的带箭头的线实例
Apr 17 #Python
matplotlib 曲线图 和 折线图 plt.plot()实例
Apr 17 #Python
Python实现自动打开电脑应用的示例代码
Apr 17 #Python
Python matplotlib绘制图形实例(包括点,曲线,注释和箭头)
Apr 17 #Python
Python读取excel文件中带公式的值的实现
Apr 17 #Python
在Matplotlib图中插入LaTex公式实例
Apr 17 #Python
python中for in的用法详解
Apr 17 #Python
You might like
全国FM电台频率大全 - 25 云南省
2020/03/11 无线电
PHP 缓存实现代码及详细注释
2010/05/16 PHP
支持中文的PHP按字符串长度分割成数组代码
2015/05/17 PHP
PHP文件缓存smarty模板应用实例分析
2016/02/26 PHP
javascript读取xml
2006/11/04 Javascript
取得父标签
2006/11/14 Javascript
理解Javascript_01_理解内存分配原理分析
2010/10/11 Javascript
JavaScript-RegExp对象只能使用一次问题解决方法
2014/06/23 Javascript
jquery插件bxslider用法实例分析
2015/04/16 Javascript
基于Javascript实现二级联动菜单效果
2016/03/04 Javascript
bootstrap和jQuery.Gantt的css冲突 如何解决
2016/05/29 Javascript
基于Bootstrap实现的下拉菜单手机端不能选择菜单项的原因附解决办法
2016/07/22 Javascript
Vuex利用state保存新闻数据实例
2017/06/28 Javascript
AngularJS实现的锚点楼层跳转功能示例
2018/01/02 Javascript
vue项目webpack中Npm传递参数配置不同域名接口
2018/06/15 Javascript
js实现搜索栏效果
2018/11/16 Javascript
axios实现文件上传并获取进度
2020/03/25 Javascript
python调用短信猫控件实现发短信功能实例
2014/07/04 Python
Python cookbook(数据结构与算法)对切片命名清除索引的方法
2018/03/13 Python
用Python实现将一张图片分成9宫格的示例
2019/07/05 Python
基于Python的ModbusTCP客户端实现详解
2019/07/13 Python
解决tensorflow训练时内存持续增加并占满的问题
2020/01/19 Python
python数据分析:关键字提取方式
2020/02/24 Python
PyQt5多线程防卡死和多窗口用法的实现
2020/09/15 Python
python中pickle模块浅析
2020/12/29 Python
美国百年历史早餐食品供应商:Wolferman’s
2017/01/18 全球购物
新加坡网上美容店:Hermo新加坡
2019/06/19 全球购物
Zalando Lounge瑞士:时尚与生活方式购物俱乐部
2020/03/12 全球购物
电子专业推荐信范文
2013/11/18 职场文书
酒店管理专业毕业生自我鉴定
2014/09/29 职场文书
常务副县长“三严三实”对照检查材料思想汇报
2014/10/05 职场文书
给病人的慰问信
2015/03/23 职场文书
Python利用folium实现地图可视化
2021/05/23 Python
postgres之jsonb属性的使用操作
2021/06/23 PostgreSQL
用Python可视化新冠疫情数据
2022/01/18 Python
Win11自动黑屏怎么办 Win11自动黑屏设置教程
2022/07/15 数码科技