Python3之并发(四)---线程锁
2024-10-21 13:24:58
一、线程锁
保证多线程数据的一致性,对锁内的资源进行锁定,同一时间只能有一个线程来修改共享的数据
多个线程同时加了同一个锁对象时,先获取到锁的线程会继续运行,未获取到锁的线程会处于堵塞状态,直到前面的线程释放锁,重新获取到锁才会往下运行
类型
threading.Lock
基本锁对象,每次只能获取一次,其他锁请求需要等锁释放后才能获取
若想对同一线程多次锁,必须等前面的锁释放,否则会变成死锁 threading.RLock
可重入锁,同一个线程中可以多次获取,也可以多次释放,但是获取和释放的次数必须要一致
锁对象的方法
Lock.acquire(blocking=True, timeout=-1)
获取锁,获取成功返回 True,否则返回 False
blocking: 默认True,堵塞没有获取到锁的线程
timeout: blocking=True时,没有获取到锁的线程的堵塞超时时间,默认-1,无限制等待;blocking=Flase时,禁止设置timeout Lock.release()
释放锁,可以从任何线程调用此函数,没有返回值
对已解锁的锁使用该方法引发 RuntimeError 异常
示例
不加锁时
取钱两次之后,余额是负数
import threading, time #账户类
class Account:
def __init__(self, account_no, balance):
#账户编号和账户余额
self.account_no = account_no
self.balance = balancedef getBlance(self):
return self.balance #提取现金方法
def draw(self, draw_amount):
if self.balance >= draw_amount:
print(threading.current_thread().name+'\t取钱成功!吐出钞票:'+str(draw_amount))
time.sleep(1)
self.balance -= draw_amount
print(threading.current_thread().name+'操作之后\t余额为:'+str(self.balance))
else:
print(threading.current_thread().name+'\t取钱失败!余额不足!\t当前余额为:'+str(self.balance)) acct = Account('986623', 1500)
thread_1 =threading.Thread(target=acct.draw, args=(800,), name='thread_1')
thread_2 =threading.Thread(target=acct.draw, args=(900,), name='thread_2')
thread_1.start()
thread_2.start()
加锁时
#账户类
class Account:
def __init__(self, account_no, balance):
#账户编号和账户余额
self.account_no = account_no
self.balance = balance self.lock = threading.RLock() def getBlance(self):
return self.balance #提取现金方法
def draw(self, draw_amount):
with self.lock:
if self.balance >= draw_amount:
print(threading.current_thread().name+'\t取钱成功!吐出钞票:'+str(draw_amount))
time.sleep(1)
self.balance -= draw_amount
print(threading.current_thread().name+'操作之后\t余额为:'+str(self.balance))
else:
print(threading.current_thread().name+'\t取钱失败!余额不足!\t当前余额为:'+str(self.balance)) acct = Account('986623', 1500)
thread_1 =threading.Thread(target=acct.draw, args=(800,), name='thread_1')
thread_2 =threading.Thread(target=acct.draw, args=(900,), name='thread_2')
thread_1.start()
thread_2.start()
死锁
当两个线程互相等待对方释放各自要加锁的锁对象时(即两个线程占用着各自将要加锁的锁对象),就会产生死锁
出现死锁时,程序会出现僵持的状态并且无法继续执行下去
避免死锁问题
避免多次锁定: 尽量避免同一个线程对多个锁对象进行锁定
具有相同的加锁顺序: 多个线程对多个锁对象加锁时,应该保证它们以相同的顺序请求加锁
使用定时锁: 程序在调用acquire()方法加锁时可以指定timeout参数,超时会自动释放锁
死锁检测: 依靠算法机制来实现的死锁预防机制
最新文章
- Maven(一)环境搭建
- nginx反向代理proxy模块相关参数
- 【阅读】提问的智慧+有效的报告BUG
- [ECNU 1624] 求交集多边形面积
- CSS Sprites的详细使用步骤
- Niagara技术文档汇总
- SpringMVC 学习笔记(两) @RequestMapping、@PathVariable和其他注意事项
- React 在服务端渲染的实现
- main方法和args参数
- Selenium+Python ---- 免登录、等待、unittest单元测试框架、PO模型
- java 集合框架(十)List
- LayoutInflater和inflate的用法,有图有真相
- React Native之配置开发环境
- mysql数据从windows导出,再导入到linux
- SkylineGlobe 如何实现二次开发加载KML文件
- Hadoop开发环境配置2-eclipse集成maven插件
- week05 06绑定滚动条 去抖动
- JavaScript动画:offset和匀速动画详解(含轮播图的实现)
- 【C++】atoi与stoi
- 类名.class和getClass()区别
热门文章
- 使用Telnet伪造邮件发送
- springboot ElasticsearchRepository date_histogram 聚合查询
- 【C++】【纯代码】获取电脑的mac地址
- Windows10使用WSL(Windows Subsystem for Linux)
- 12组-Beta冲刺-5/5
- sleep(0)的意义
- sxt_(001_002)_web简介
- Cgroup学习笔记3—代码实现—相关结构和全局变量
- windows远程桌面之前用于连接到xxx的凭据无法工作
- 如何下载zoom上别人录制的视频?