浅谈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 自动补全(vim)
Nov 30 Python
利用python爬取斗鱼app中照片方法实例
Dec 03 Python
PyQt5 pyqt多线程操作入门
May 05 Python
matplotlib给子图添加图例的方法
Aug 03 Python
Python实现E-Mail收集插件实例教程
Feb 06 Python
Django框架中间件(Middleware)用法实例分析
May 24 Python
Python流行ORM框架sqlalchemy安装与使用教程
Jun 04 Python
Django 如何使用日期时间选择器规范用户的时间输入示例代码详解
May 22 Python
解决python pandas读取excel中多个不同sheet表格存在的问题
Jul 14 Python
Selenium+BeautifulSoup+json获取Script标签内的json数据
Dec 07 Python
用python发送微信消息
Dec 21 Python
利用Python判断整数是否是回文数的3种方法总结
Jul 07 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利用超级全局变量$_POST来接收表单数据的实例
2016/11/05 PHP
PHP实现的简单AES加密解密算法实例
2017/05/29 PHP
5 cool javascript apps
2007/03/24 Javascript
jQuery EasyUI API 中文文档 - TreeGrid 树表格使用介绍
2011/11/21 Javascript
两种方法实现在HTML页面加载完毕后运行某个js
2014/06/16 Javascript
javascript实现可拖动变色并关闭层窗口实例
2015/05/15 Javascript
JS选中checkbox后获取table内一行TD所有数据的方法
2015/07/01 Javascript
js实现图片点击左右轮播
2015/07/08 Javascript
DOM事件阶段以及事件捕获与事件冒泡先后执行顺序(图文详解)
2015/08/18 Javascript
在 Express 中使用模板引擎
2015/12/10 Javascript
JavaScript中绑定事件的三种方式及去除绑定
2016/11/05 Javascript
原生js实现打字动画游戏
2017/02/04 Javascript
JavaScript实现审核流程状态的动态显示进度条
2017/03/15 Javascript
基于Jquery Ajax type的4种类型(详解)
2017/08/02 jQuery
JS跳转手机站url的若干注意事项
2017/10/18 Javascript
vue组件watch属性实例讲解
2017/11/07 Javascript
vue 中基于html5 drag drap的拖放效果案例分析
2018/11/01 Javascript
如何使用puppet替换文件中的string
2018/12/06 Javascript
Vue实现类似Spring官网图片滑动效果方法
2019/03/01 Javascript
layer.confirm点击第一个按钮关闭弹出框的方法
2019/09/09 Javascript
解决vue项目,npm run build后,报路径错的问题
2020/08/13 Javascript
[01:39]2014DOTA2国际邀请赛 Newbee经理CU专访队伍火力全开
2014/07/15 DOTA
设计模式中的原型模式在Python程序中的应用示例
2016/03/02 Python
详解python上传文件和字符到PHP服务器
2017/11/24 Python
Python中.join()和os.path.join()两个函数的用法详解
2018/06/11 Python
利用python脚本如何简化jar操作命令
2019/02/24 Python
pyinstaller将含有多个py文件的python程序做成exe
2020/04/29 Python
《钱学森》听课反思
2014/03/01 职场文书
关于环保的建议书
2014/05/12 职场文书
导师就业推荐信范文
2014/05/22 职场文书
化妆品活动策划方案
2014/05/23 职场文书
争当四好少年演讲稿
2014/09/13 职场文书
2016年六一儿童节开幕词
2016/03/04 职场文书
Python anaconda安装库命令详解
2021/10/16 Python
Java生成日期时间存入Mysql数据库的实现方法
2022/03/03 Java/Android
Win10服务全部禁用了怎么启动?Win10服务全部禁用解决方法
2022/09/23 数码科技