浅谈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 pickle 和 shelve模块的用法
Sep 16 Python
Python内置函数的用法实例教程
Sep 08 Python
python获取当前日期和时间的方法
Apr 30 Python
Django框架教程之正则表达式URL误区详解
Jan 28 Python
python实现在pandas.DataFrame添加一行
Apr 04 Python
使用pytorch和torchtext进行文本分类的实例
Jan 08 Python
postman和python mock测试过程图解
Feb 22 Python
Python GUI编程学习笔记之tkinter中messagebox、filedialog控件用法详解
Mar 30 Python
Python并发请求下限制QPS(每秒查询率)的实现代码
Jun 05 Python
Spring @Enable模块驱动原理及使用实例
Jun 23 Python
Python HTMLTestRunner如何下载生成报告
Sep 04 Python
用python 绘制茎叶图和复合饼图
Feb 26 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
Amazon Prime Video平台《无限住人 -IMMORTAL-》2020年开始TV放送!
2020/03/06 日漫
PHP 编程安全性小结
2010/01/08 PHP
php中数字0和空值的区别分析
2014/06/05 PHP
php中使用Ajax时出现Error(c00ce56e)的详细解决方案
2014/11/03 PHP
ThinkPHP模板输出display用法分析
2014/11/26 PHP
JavaScript与HTML结合的基本使用方法整理
2015/10/12 PHP
php微信开发之百度天气预报
2016/11/18 PHP
PHP 二级子目录(后台目录)设置二级域名
2017/03/02 PHP
jquery操作select option 的代码小结
2011/06/21 Javascript
基于jquery的多功能软键盘插件
2012/07/25 Javascript
js比较和逻辑运算符的介绍
2013/03/10 Javascript
浅析onsubmit校验表单时利用ajax的return false无效问题
2013/07/10 Javascript
javascript实现简单的html5视频播放器
2015/05/06 Javascript
简单谈谈ES6的六个小特性
2016/11/18 Javascript
微信小程序 slider 详解及实例代码
2017/01/10 Javascript
使用Promise链式调用解决多个异步回调的问题
2017/01/15 Javascript
JavaScript实现弹出广告功能
2017/03/30 Javascript
详解react-router4 异步加载路由两种方法
2017/09/12 Javascript
vue获取input输入值的问题解决办法
2017/10/17 Javascript
js使用cookie实现记住用户名功能示例
2019/06/13 Javascript
[01:53]2016完美“圣”典风云人物:Maybe专访
2016/12/05 DOTA
[55:44]完美世界DOTA2联赛决赛 FTD vs Phoenix 第二场 11.08
2020/11/11 DOTA
详解Python中find()方法的使用
2015/05/18 Python
星球大战与Python之间的那些事
2016/01/07 Python
Tesserocr库的正确安装方式
2018/10/19 Python
详解python selenium 爬取网易云音乐歌单名
2019/03/28 Python
Python中remove漏删和索引越界问题的解决
2020/03/18 Python
Python如何使用bokeh包和geojson数据绘制地图
2020/03/21 Python
解决reload(sys)后print失效的问题
2020/04/25 Python
美国家用电器和电子产品商店:Abt
2016/09/06 全球购物
英国在线花园中心:You Garden
2018/06/03 全球购物
C++的几个面试题附答案
2016/08/03 面试题
中餐厅主管的职责范文
2014/02/04 职场文书
三八妇女节慰问信
2015/02/14 职场文书
商务代表岗位职责
2015/02/15 职场文书
Shell中的单中括号和双中括号的用法详解
2022/12/24 Servers