浅谈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调用命令行进度条的方法
May 05 Python
用Python登录好友QQ空间点赞的示例代码
Nov 04 Python
对Python多线程读写文件加锁的实例详解
Jan 14 Python
使用Template格式化Python字符串的方法
Jan 22 Python
python使用pygame模块实现坦克大战游戏
Mar 25 Python
python 寻找离散序列极值点的方法
Jul 10 Python
python在OpenCV里实现投影变换效果
Aug 30 Python
python做接口测试的必要性
Nov 20 Python
Python生成器传参数及返回值原理解析
Jul 22 Python
Python中os模块的简单使用及重命名操作
Apr 17 Python
python numpy中multiply与*及matul 的区别说明
May 26 Python
Python Django / Flask如何使用Elasticsearch
Apr 19 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
一段php加密解密的代码
2006/10/09 PHP
php记录日志的实现代码
2011/08/08 PHP
smarty获得当前url的方法分享
2014/02/14 PHP
PHP实现数字补零功能的2个函数介绍
2014/05/12 PHP
JS 对输入框进行限制(常用的都有)
2013/07/30 Javascript
js利用数组length属性清空和截短数组的小例子
2014/01/15 Javascript
原生Ajax 和jQuery Ajax的区别示例分析
2014/12/17 Javascript
了不起的node.js读书笔记之例程分析
2014/12/22 Javascript
JavaScript对数字的判断与处理实例分析
2015/02/02 Javascript
浅谈EasyUI中编辑treegrid的方法
2015/03/01 Javascript
JavaScript实现的圆形浮动标签云效果实例
2015/08/06 Javascript
jQuery Form 表单提交插件之formSerialize,fieldSerialize,fieldValue,resetForm,clearForm,clearFields的应用
2016/01/23 Javascript
js阻止浏览器默认行为的简单实例
2016/05/15 Javascript
浅谈javascript中new操作符的原理
2016/06/07 Javascript
AngularJS基础 ng-options 指令详解
2016/08/02 Javascript
JavaScript比较两个数组的内容是否相同(推荐)
2017/05/02 Javascript
使用jQuery.Pin垂直滚动时固定导航
2017/05/24 jQuery
详解微信小程序Page中data数据操作和函数调用
2017/09/27 Javascript
Vue中封装input组件的实例详解
2017/10/17 Javascript
全面介绍vue 全家桶和项目实例
2017/12/27 Javascript
javascript中UMD规范的代码推演
2018/08/29 Javascript
VSCode launch.json配置详细教程
2020/06/18 Javascript
[53:43]VP vs NewBee Supermajor 胜者组 BO3 第三场 6.5
2018/06/06 DOTA
Python中设置变量访问权限的方法
2015/04/27 Python
Python的Flask开发框架简单上手笔记
2015/11/16 Python
pygame实现俄罗斯方块游戏(基础篇1)
2019/10/29 Python
Pytorch 实现sobel算子的卷积操作详解
2020/01/10 Python
matplotlib 生成的图像中无法显示中文字符的解决方法
2020/06/10 Python
详解基于python的全局与局部序列比对的实现(DNA)
2020/10/07 Python
Python数据模型与Python对象模型的相关总结
2021/01/26 Python
墨西哥网上购物:Linio墨西哥
2016/10/20 全球购物
四群教育工作实施方案
2014/03/26 职场文书
新闻学专业求职信
2014/07/28 职场文书
2014旅游局领导班子四风问题对照检查材料思想汇报
2014/09/19 职场文书
离职证明格式样本
2015/06/12 职场文书
排查Tomcat进程假死的问题
2022/05/06 Servers