本文实例讲述了Python多线程操作之互斥锁、递归锁、信号量、事件。分享给大家供大家参考,具体如下:
import time,threading
x=6
def run1():
print("run1我拿到了数据:",x)
print("我现在还不想操作,先睡一下")
time.sleep(3)
print("再看一下数据,稳一稳",x)
def run2():
global x
print("run2我拿到了数据:", x)
x=5
print(x)
t1=threading.Thread(target=run1)
t2=threading.Thread(target=run2)
t1.start()
t2.start()
t1.join()
t2.join()
使用互斥锁来更改上段代码
import time,threading
x=6
def run1():
lock.acquire()
global x
print("run1我拿到了数据,x=",x)
print("我现在还不想操作,先睡一下")
time.sleep(3)
print("再看一下数据,稳一稳,x=",x)
x+=1
print("run1操作完毕:x=",x)
lock.release()
def run2():
lock.acquire()
global x
print("run2我拿到了数据:", x)
x+=1
print("run2操作完毕:x=",x)
lock.release()
lock=threading.Lock()#生成一个锁对象
t1=threading.Thread(target=run1)
t2=threading.Thread(target=run2)
t1.start()
t2.start()
start_time=time.time()
t1.join()
t2.join()
print("最终的x=",x)
print(time.time()-start_time)#3.0多说明,由于受到锁的影响,run2要等待run1释放lock,所以变成了串行
这种互斥锁在操作系统中可以称作“临界区”,如果想了解更多:
https://baike.baidu.com/item/%E4%B8%B4%E7%95%8C%E5%8C%BA/8942134?fr=aladdin
【以过独木桥为例】:桥只能容一个人通过,A只能看得到北边桥上有没有人,看不到南边桥有没有人,当他看到北边桥没人就会过桥,等到他到桥中间才能看到南边桥有没有人,B情况相反:【于是当两个人一起过桥的时候就会发生死锁】
import threading,time
"""
A只能看得到北边桥上有没有人,看不到南边桥有没有人,
当他看到北边桥没人就会过桥,等到他到桥中间才能看到南边桥有没有人
"""
def A():
lockNorth.acquire()#拿到北边桥的锁
print("A过桥北")
time.sleep(3)#过桥中
lockSorth.acquire()#企图过到南边桥,
print("A过桥南")
time.sleep(3) # 过桥中
lockSorth.release()
lockNorth.release()
print("A过桥成功")
"""
B只能看得到南边桥上有没有人,看不到北边桥有没有人,
当他看到南边桥没人就会过桥,等到他到桥中间才能看到北边桥有没有人
"""
def B():
lockSorth.acquire() # 企图过到南边桥,
print("B过桥南")
time.sleep(3) # 过桥中
lockNorth.acquire() # 拿到北边桥的锁
print("B过桥北")
time.sleep(3) # 过桥中
lockNorth.release()
lockSorth.release()
print("B过桥成功")
lockNorth=threading.Lock()
lockSorth=threading.Lock()
tA=threading.Thread(target=A)
tB=threading.Thread(target=B)
tA.start()
tB.start()
tA.join()
tB.join()
使用递归锁来解决上面的死锁问题:
import threading,time
"""
A只能看得到北边桥上有没有人,看不到南边桥有没有人,
当他看到北边桥没人就会过桥,等到他到桥中间才能看到南边桥有没有人
"""
def A():
lock.acquire()#拿到北边桥的锁
print("A过桥北")
time.sleep(3)#过桥中
lock.acquire()#企图过到南边桥,
print("A过桥南")
time.sleep(3) # 过桥中
lock.release()
lock.release()
print("A过桥成功")
"""
B只能看得到南边桥上有没有人,看不到北边桥有没有人,
当他看到南边桥没人就会过桥,等到他到桥中间才能看到北边桥有没有人
"""
def B():
lock.acquire() # 拿南桥锁,
print("B过桥南")
time.sleep(3) # 过桥中
lock.acquire() # 企图拿北桥的锁
print("B过桥北")
time.sleep(3) # 过桥中
lock.release()
lock.release()
print("B过桥成功")
lock=threading.RLock()
tA=threading.Thread(target=A)
tB=threading.Thread(target=B)
tA.start()
tB.start()
tA.join()
tB.join()
【由于本质是一把锁,A拿到锁后,B要等待】
信号量可以限制进入的线程的数量。
import threading,time
def run():
s.acquire()
print("hello")
time.sleep(1.5)
s.release()
s=threading.BoundedSemaphore(3)#限制3个
threading_list=[]
for i in range(12):#创建12个线程
obj=threading.Thread(target=run)
obj.setDaemon(True) # 设置守护线程,避免干扰主线程运行,并行等待
obj.start()
for i in range(4):
print("")#为了把结果分割,可以清楚看出分为了三组
time.sleep(1.5)
#结果分为三组是因为运行的太快了,三个线程装入的时间差太小
import threading,time
def read():
while True:
if event.is_set():
print("事件已设置,我要读了!!!!")
time.sleep(1)
else:#事件未设置
print("还没写好,我要等咯")
event.wait()#那么就等着咯
#如果等到了
print("终于等到了!那么我又可以读了")
time.sleep(1)
def write():
event.clear()#初始设空
while True:
time.sleep(3)#写
event.set()#设置事件,一旦set,那么读者wait就有返回了,读者可以继续运行了
print("write:写好了")
time.sleep(2)#等人读
event.clear()#清除事件
event=threading.Event() #创建事件对象
t1=threading.Thread(target=write)
t2=threading.Thread(target=read)
t1.start()
t2.start()
t1.join()
t2.join()
"""结果显示:读者确实一直在等待写者写好"""
更多关于Python相关内容感兴趣的读者可查看本站专题:《Python进程与线程操作技巧总结》、《Python数据结构与算法教程》、《Python函数使用技巧总结》、《Python字符串操作技巧汇总》、《Python入门与进阶经典教程》、《Python+MySQL数据库程序设计入门教程》及《Python常见数据库操作技巧汇总》
希望本文所述对大家Python程序设计有所帮助。
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。