多任务-线程之资源竞争问题(互斥锁)
1.在多线程中,不可避免的一个问题,就是全局变量资源存在着被多个线程调用的问题,在调用的过程中就存在着资源竞争
2.这种资源竞争是如何产生的呢?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | import threading import time g_num = 0 def work1(num): global g_num for i in range (num): g_num + = 1 print ( "----in work1, g_num is %d---" % g_num) def work2(num): global g_num for i in range (num): g_num + = 1 print ( "----in work2, g_num is %d---" % g_num) print ( "---线程创建之前g_num is %d---" % g_num) t1 = threading.Thread(target = work1, args = ( 100 ,)) t1.start() t2 = threading.Thread(target = work2, args = ( 100 ,)) t2.start() while len (threading. enumerate ()) ! = 1 : time.sleep( 1 ) print ( "2个线程对同一个全局变量操作之后的最终结果是:%s" % g_num) |
如同上述代码,当线程执行次数有限时,全局资源不会发生大的变化,但是当高并发时,就会产生资源竞争问题,如以下代码:
import threading import time g_num = 0 def work1(num): global g_num for i in range(num): g_num += 1 print("----in work1, g_num is %d---"%g_num) def work2(num): global g_num for i in range(num): g_num += 1 print("----in work2, g_num is %d---"%g_num) print("---线程创建之前g_num is %d---"%g_num) t1 = threading.Thread(target=work1, args=(1000000,)) t1.start() t2 = threading.Thread(target=work2, args=(1000000,)) t2.start() while len(threading.enumerate()) != 1: time.sleep(1) print("2个线程对同一个全局变量操作之后的最终结果是:%s" % g_num)
3.如何解决资源竞争问题?
当存在多个线程或者进程同时调用一个全局变量资源,并且会对它进行修改时,可以采用上锁这个方法,来解决资源竞争问题。
首先,需要了解什么叫做资源竞争?
资源竞争是指,一个全局变量资源在多个线程或者进程中被同时调用,造成该全局变量资源不断的被修改。
解决方法:采用全局变量锁,每当线程调用全局变量时,就将该资源上锁,不允许被调用,只有当调用结束后才打开锁,这里引入互斥锁,能够保证全局变量资源的安全。
互斥锁的两种状态:锁定/非锁定
解决资源竞争的好处:互斥锁保证了每次只有一个线程进行写入操作,从而保证了多线程情况下数据的正确性。
4.互斥锁的定义
当在请求之前,资源没有被上锁,那么请求并不会堵塞;如果在请求之前,是被锁上的, 那么请求就处于一个堵塞状态,只有当前得锁被打开之后,才能在次上锁。
互斥锁的优缺点:
优点:确保了某段关键代码只能由一个线程从头到尾完整地执行
缺点:阻止了多线程并发执行,包含锁的某段代码实际上只能以单线程模式执行,效率就大大地下降了
由于可以存在多个锁,不同的线程持有不同的锁,并试图获取对方持有的锁时,可能会造成死锁
1 2 3 4 5 6 7 8 | # 创建锁 mutex = threading.Lock() # 锁定 mutex.acquire() # 释放 mutex.release() |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· Ollama——大语言模型本地部署的极速利器
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· Windows编程----内核对象竟然如此简单?
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用