浅谈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字典序问题实例
Sep 26 Python
python 找出list中最大或者最小几个数的索引方法
Oct 30 Python
Python 从列表中取值和取索引的方法
Dec 25 Python
PyQt5内嵌浏览器注入JavaScript脚本实现自动化操作的代码实例
Feb 13 Python
几个适合python初学者的简单小程序,看完受益匪浅!(推荐)
Apr 16 Python
Python3使用xml.dom.minidom和xml.etree模块儿解析xml文件封装函数的方法
Sep 23 Python
Python importlib动态导入模块实现代码
Apr 16 Python
在python image 中实现安装中文字体
May 16 Python
Python调用shell cmd方法代码示例解析
Jun 18 Python
python中HTMLParser模块知识点总结
Jan 25 Python
Python 里最强的地图绘制神器
Mar 01 Python
Python实现科学占卜 让视频自动打码
Apr 09 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
APMServ使用说明
2006/10/23 PHP
PHP配置文件中最常用四个ini函数
2007/03/19 PHP
中英文字符串翻转函数
2008/12/09 PHP
基于pear auth实现登录验证
2010/02/26 PHP
yii2.0之GridView自定义按钮和链接用法
2014/12/15 PHP
Symfony数据校验方法实例分析
2015/01/26 PHP
PHP中set_include_path()函数相关用法分析
2016/07/18 PHP
Yii2.0框架behaviors方法使用实例分析
2019/09/30 PHP
PHP7创建销毁session的实例方法
2020/02/03 PHP
基于JS实现的笛卡尔乘积之商品发布
2016/05/13 Javascript
jQuery和hwSlider实现内容响应式可触控滑动切换效果附源码下载(二)
2016/06/22 Javascript
JavaScript运动框架 多物体任意值运动(三)
2017/05/17 Javascript
vue-quill-editor实现图片上传功能
2017/08/08 Javascript
vue-cli项目中使用Mockjs详解
2018/05/14 Javascript
AngularJS $http post 传递参数数据的方法
2018/10/09 Javascript
微信小程序跳转到其他网页(外部链接)的实现方法
2019/09/20 Javascript
python实现ipsec开权限实例
2014/11/11 Python
Django的models中on_delete参数详解
2019/07/16 Python
python matplotlib 画dataframe的时间序列图实例
2019/11/20 Python
Pytorch之卷积层的使用详解
2019/12/31 Python
基于Python3.6中的OpenCV实现图片色彩空间的转换
2020/02/03 Python
浅析matlab中imadjust函数
2020/02/27 Python
Python Scrapy图片爬取原理及代码实例
2020/06/12 Python
CSS3实现简易版的刮刮乐效果
2016/09/27 HTML / CSS
用CSS3绘制三角形的简单方法
2015/07/17 HTML / CSS
浅析css3中matrix函数的使用
2016/06/06 HTML / CSS
德国宠物用品、宠物食品及水族馆网上商店:ZooRoyal
2017/07/09 全球购物
初中生学习生活的自我评价
2013/11/20 职场文书
大学四年的个人自我评价
2014/01/14 职场文书
上课迟到检讨书300字
2014/10/15 职场文书
2014年班级工作总结范文
2014/12/23 职场文书
债务纠纷起诉书
2015/05/20 职场文书
教育教学读书笔记
2015/07/02 职场文书
生产车间管理制度
2015/08/04 职场文书
MongoDB数据库的安装步骤
2021/06/18 MongoDB
3050和2060哪个好 性能差多少 差距有多大 谁更有性价比
2022/06/17 数码科技