python基础一 day40 线程锁 信号量 事件
锁:
import time from threading import Lock,Thread # Lock 互斥锁 # def func(lock): # global n # lock.acquire() # temp = n # time.sleep(0.2) # n = temp - 1 # lock.release() # # n = 10 # t_lst = [] # lock = Lock() # for i in range(10): # t = Thread(target=func,args=(lock,)) # t.start() # t_lst.append(t) # for t in t_lst: t.join() # print(n)
# 科学家吃面 # noodle_lock = Lock() # fork_lock = Lock() # def eat1(name): # noodle_lock.acquire() # print('%s拿到面条啦'%name) # fork_lock.acquire() # print('%s拿到叉子了'%name) # print('%s吃面'%name) # fork_lock.release() # noodle_lock.release() # # def eat2(name): # fork_lock.acquire() # print('%s拿到叉子了'%name) # time.sleep(1) # noodle_lock.acquire() # print('%s拿到面条啦'%name) # print('%s吃面'%name) # noodle_lock.release() # fork_lock.release() # # Thread(target=eat1,args=('alex',)).start() # Thread(target=eat2,args=('Egon',)).start() # Thread(target=eat1,args=('bossjin',)).start() # Thread(target=eat2,args=('nezha',)).start()
from threading import RLock # 递归锁 fork_lock = noodle_lock = RLock() # 一个钥匙串上的两把钥匙 def eat1(name): noodle_lock.acquire() # 一把钥匙 print('%s拿到面条啦'%name) fork_lock.acquire() print('%s拿到叉子了'%name) print('%s吃面'%name) fork_lock.release() noodle_lock.release() def eat2(name): fork_lock.acquire() print('%s拿到叉子了'%name) time.sleep(1) noodle_lock.acquire() print('%s拿到面条啦'%name) print('%s吃面'%name) noodle_lock.release() fork_lock.release() Thread(target=eat1,args=('alex',)).start() Thread(target=eat2,args=('Egon',)).start() Thread(target=eat1,args=('bossjin',)).start() Thread(target=eat2,args=('nezha',)).start()
递归锁RLock:在一个线程里可以多次acquire(),解决死锁问题
进程也有死锁问题,当在同一个线程或者同一个进程中,用到两把及以上的互斥锁的时候,容易出现死锁
为什么加锁:全局解释器锁(GIL)是给线程加了锁,是为了避免多个线程同一时间对一个数据进行操作,
但是并不能避免时间片的轮转带来的数据不安全性
lock.acquire()会阻塞
信号量:
import time from threading import Semaphore,Thread def func(sem,a,b): sem.acquire() time.sleep(1) print(a+b) sem.release() sem = Semaphore(4) for i in range(10): t = Thread(target=func,args=(sem,i,i+5)) t.start()
事件:
# 事件被创建的时候
# False状态
# wait() 阻塞
# True状态
# wait() 非阻塞
# clear 设置状态为False
# set 设置状态为True
# 数据库 - 文件夹
# 文件夹里有好多excel表格
# 1.能够更方便的对数据进行增删改查
# 2.安全访问的机制
# 起两个线程
# 第一个线程 : 连接数据库
# 等待一个信号 告诉我我们之间的网络是通的
# 连接数据库
# 第二个线程 : 检测与数据库之间的网络是否连通
# time.sleep(0,2) 2
# 将事件的状态设置为True
import time import random from threading import Thread,Event def connect_db(e): count = 0 while count < 3: e.wait(0.5) # 状态为False的时候,我只等待1s就结束 if e.is_set() == True: print('连接数据库') break else: count += 1 print('第%s次连接失败'%count) else: raise TimeoutError('数据库连接超时') def check_web(e): time.sleep(random.randint(0,3)) e.set() e = Event() t1 = Thread(target=connect_db,args=(e,)) t2 = Thread(target=check_web,args=(e,)) t1.start() t2.start()
作者:静默虚空
欢迎任何形式的转载,但请务必注明出处。
限于本人水平,如果文章和代码有表述不当之处,还请不吝赐教。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Java 中堆内存和栈内存上的数据分布和特点
· 开发中对象命名的一点思考
· .NET Core内存结构体系(Windows环境)底层原理浅谈
· C# 深度学习:对抗生成网络(GAN)训练头像生成模型
· .NET 适配 HarmonyOS 进展
· 手把手教你更优雅的享受 DeepSeek
· 腾讯元宝接入 DeepSeek R1 模型,支持深度思考 + 联网搜索,好用不卡机!
· AI工具推荐:领先的开源 AI 代码助手——Continue
· 探秘Transformer系列之(2)---总体架构
· V-Control:一个基于 .NET MAUI 的开箱即用的UI组件库