Python多任务学习笔记(4)——多线程共享全局变量产生问题的解决方案之互斥锁
文章目录
在Python多任务学习笔记(3)——多线程共享全局变量及可能产生的问题中,我们知道Python中多线程共享全局变量,但是这会产生如前文中所描述的问题,name应该如何解决这个问题呢?
1. 线程同步的概念
此处同不是取同时之意,而是取协同、配合之意,比如在前述Python多线程中,线程1和2之间应该协同递增变量global_num的值,而不是同时,否则就会产生意料之外的情形。
具体来说,以Python多任务学习笔记(3)——多线程共享全局变量及可能产生的问题中的情形为例,如果可以实现:线程1在执行语句global_num += 1时,线程2无法修改global_num的值;反之线程2在执行语句global_num += 1时,线程1也无法修改global_num的值。这种功能就可以叫线程同步。
2. 线程同步的实现——互斥锁
互斥锁是最简单的一种线程同步机制,可简单将其理解为可以对多线程共享的资源进行锁定的操作。
如:还是以Python多任务学习笔记(3)——多线程共享全局变量及可能产生的问题中的情形为例,如果某个线程想要修改其和另一条线程共享的全局变量global_num(即资源),该线程可对其进行上锁,这样另一条线程就无法修改该全局变量,等到该线程成功修改该全局变量后,再将该全局变量解锁,则另一条线程便也可对其执行上锁操作后修改其值,如此循环往复,就解决了意料之外的情形。
3. Python中互斥锁的实现
Python中的threading模块中提供的Lock类实现了互斥锁。
针对Python多任务学习笔记(3)——多线程共享全局变量及可能产生的问题中的情形,通过Python中的互斥锁,有以下代码可解决问题:
import threading # 定义一个全局变量 global_num = 0 def test1(num): global global_num for i in range(num): # 为互斥锁上锁,如果之前未被其他线程上锁,则上锁成功 # 否则,阻塞直到其他线程解锁后才成功上锁 mutual_lock.acquire() global_num += 1 mutual_lock.release() print("Inside the Thread Denoted by " "Function test1() global_num = %d" % global_num) def test2(num): global global_num for i in range(num): mutual_lock.acquire() global_num += 1 mutual_lock.release() print("Inside the Thread Denoted by " "Function test2() global_num = %d" % global_num) # 创建一全局互斥锁对象 mutual_lock = threading.Lock() def main(): thread1 = threading.Thread(target=test1, args=(1000000,)) thread2 = threading.Thread(target=test2, args=(1000000,)) thread1.start() thread2.start() # 等待两个线程均运行结束 while True: if len(threading.enumerate()) == 1: break print("Inside the Main Thread num = %d" % global_num) if __name__ == "__main__": main()
上述代码的运行结果为:
Inside the Thread Denoted by Function test2() global_num = 1853037
Inside the Thread Denoted by Function test1() global_num = 2000000
Inside the Main Thread global_num = 2000000
值得注意的是,上述采用互斥锁的代码在运行之后,虽然保证了最终结果的准确性,即global_num最终为2000000,但是在子线程2中,最终打印为1853037。
产生上述现象的原因在于,CPU通过时间片轮转的方式调度线程时并非完全雨露均沾(即线程1、2按照各自一次的频率对global_num进行累加),也就是说:可能线程2在解锁后,线程1并没有能够马上获取锁,而是线程2又获取了锁,最后导致线程2抢先完成1000000次增加,而此时线程1仅完成了853037次,由此造成了此现象。
- 点赞
- 收藏
- 分享
- 文章举报
- python 多线程共享全局变量的问题
- 【python】多线程共享全局变量问题
- 浅谈python多线程和多线程变量共享问题介绍
- Python3-多线程共享全局变量
- java多线程全局变量共享问题
- python多线程-共享全局变量
- 19、多任务-线程-共享全局变量产生的问题资源竞争
- day 0807 多线程—共享全局变量问题
- Java多线程共享全局变量问题
- 多线程-共享全局变量(python版)
- 浅谈Python 多进程默认不能共享全局变量的问题
- python自定义线程类的使用与共享全局变量的问题
- Python多任务学习笔记(5)——使用互斥锁可能产生的问题之死锁
- python中的多线程-共享全局变量
- 多线程:利用互斥锁来处理全局变量的互斥问题
- linux动态链接库全局变量共享问题&DLL共享数据段
- Python在函数中使用全局变量的问题
- python多线程安全问题(两种解决方案)
- python unittest TestCase间共享数据(全局变量的使用)
- 关于百度EChart 与dataTables 之间交互问题的解决方案(利用js全局变量)