RLock(递归锁)
import threading, time
def run1():
print("grab the first part data")
lock.acquire()#进入大门后的一间屋子
global num
num += 1
lock.release()#退出这间屋子
return num def run2():
print("grab the second part data")
lock.acquire()#进入大门后的另一间屋子,和上个屋子平行
global num2
num2 += 1
lock.release()#退出这间屋子
return num2 def run3():
lock.acquire()#第一道门,大门
res = run1()
print('--------between run1 and run2-----')
res2 = run2()
lock.release()
print(res, res2) if __name__ == '__main__': num, num2 = 0, 0
lock = threading.Lock()
for i in range(10):
t = threading.Thread(target=run3)
t.start()
#一共11个线程
while threading.active_count() != 1:
print(threading.active_count())
else:#只剩一个线程了,表示所有子线程执行完毕
print('----all threads done---')
print(num, num2)
结果:
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
一直执行,不停的打印11......,锁死了,怎么办?其实是各个门之间的钥匙混了,所以打不开锁了,锁死了,需要以下操作才能解决。
RLock(递归锁)
说白了就是在一个大锁中还要再包含子锁
import threading, time
def run1():
print("grab the first part data")
lock.acquire()
global num
num += 1
lock.release()
return num def run2():
print("grab the second part data")
lock.acquire()
global num2
num2 += 1
lock.release()
return num2 def run3():
lock.acquire()
res = run1()
print('--------between run1 and run2-----')
res2 = run2()
lock.release()
print(res, res2) if __name__ == '__main__': num, num2 = 0, 0
lock = threading.RLock()#改为递归锁
for i in range(10):
t = threading.Thread(target=run3)
t.start() while threading.active_count() != 1:
print(threading.active_count())
else:
print('----all threads done---')
print(num, num2)
结果:
D:\Anaconda3\python.exe C:/Users/Administrator/Desktop/py_work/lib/aa.py
grab the first part data
--------between run1 and run2-----
grab the second part data
1 1
grab the first part data
--------between run1 and run2-----
grab the second part data
2 2
grab the first part data
--------between run1 and run2-----
grab the second part data
3 3
grab the first part data
--------between run1 and run2-----
grab the second part data
4 4
grab the first part data
--------between run1 and run2-----
grab the second part data
5 5
grab the first part data
--------between run1 and run2-----
grab the second part data
6 6
grab the first part data
--------between run1 and run2-----
grab the second part data
7 7
grab the first part data
--------between run1 and run2-----
grab the second part data
8 8
grab the first part data
--------between run1 and run2-----
grab the second part data
9 9
grab the first part data
--------between run1 and run2-----
grab the second part data
10 10
----all threads done---
10 10 Process finished with exit code 0
概念总结:
死锁: 是指两个或两个以上的进程或线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程
那么怎么解决死锁现象呢?
解决方法,递归锁:在Python中为了支持在同一线程中多次请求同一资源,python提供了可重入锁RLock。这个RLock内部维护着一个Lock和一个counter变量,counter记录了acquire的次数,从而使得资源可以被多次require。直到一个线程所有的acquire都被release,其他的线程才能获得资源。上面的例子如果使用RLock代替Lock,则不会发生死锁。
threading.Lock和threading.RLock区别:RLock允许在同一线程中被多次acquire。而Lock却不允许这种情况。注意:如果使用RLock,那么acquire和release必须成对出现,即调用了n次acquire,必须调用n次的release才能真正释放所占用的琐。
RLock(递归锁)的更多相关文章
- 死锁的原因及解决办法RLock递归锁
死锁 说到死锁,可以讲一个科学家吃面的问题: 有几个科学家在一张桌子旁,桌子上只有一把筷子和一碗面,我们将面和筷子都加锁.这是可能会导致一个科学家抢到面,另一个科学家抢到筷子,这是就全部阻塞了,这就是 ...
- setdeamon 设置 线程为守护线程, (lock线程锁, BoundedSemaphore,rlock递归锁 ) 三种锁
1.setdeamon 当主程序执行完时,子程序自动被销毁 ,内存自动被收回 例一: import threading, time def run(n): print('run %s'%n) time ...
- Python 递归锁
import time from threading import Thread, Lock, RLock def f1(locA, locB): # print('xxxx') # time.sle ...
- python 线程(创建2种方式,锁,死锁,递归锁,GIL锁,守护进程)
###############总结############ 线程创建的2种方式(重点) 进程:资源分配单位 线程:cpu执行单位(实体) 线程的创建和销毁的开销特别小 线程之间资源共享,是同一个 ...
- 6-[多线程]-互斥锁、GIL、死锁、递归锁、信号量
1.互斥锁(排他锁) (1)不加锁的情况下 并发控制问题:多个事务并发执行,可能产生操作冲突,出现下面的3种情况 丢失修改错误 不能重复读错误 读脏数据错误 # mutex from threadin ...
- 线程、进程、daemon、GIL锁、线程锁、递归锁、信号量、计时器、事件、队列、多进程
# 本文代码基于Python3 什么是进程? 程序并不能单独运行,只有将程序装载到内存中,系统为它分配资源才能运行,而这种执行的程序就称之为进程.程序和进程的区别就在于:程序是指令的集合,它是进程运行 ...
- Python死锁与递归锁
Lock() 互斥锁会导致死锁,用RLock()递归锁代替. 递归锁:可以连续acquire多次,每acquire一次计数器+1(无论acquire的是哪个锁),只有计数为0才能被acquire mu ...
- 线程全局修改、死锁、递归锁、信号量、GIL以及多进程和多线程的比较
线程全局修改 x = 100 def func1(): global x print(x) changex() print(x) def changex(): global x x = 50 func ...
- python 之 并发编程(守护线程与守护进程的区别、线程互斥锁、死锁现象与递归锁、信号量、GIL全局解释器锁)
9.94 守护线程与守护进程的区别 1.对主进程来说,运行完毕指的是主进程代码运行完毕2.对主线程来说,运行完毕指的是主线程所在的进程内所有非守护线程统统运行完毕,主线程才算运行完毕详细解释:1.主 ...
- python并发编程-多线程实现服务端并发-GIL全局解释器锁-验证python多线程是否有用-死锁-递归锁-信号量-Event事件-线程结合队列-03
目录 结合多线程实现服务端并发(不用socketserver模块) 服务端代码 客户端代码 CIL全局解释器锁****** 可能被问到的两个判断 与普通互斥锁的区别 验证python的多线程是否有用需 ...
随机推荐
- Sping中使用Junit进行测试
分析: 1.应用程序的入口 main方法2.junit单元测试中,没有main方法也能执行 junit集成了一个main方法 该方法就会判断当前测试类中哪些方法有 @Test注解 junit就让有Te ...
- profiler Reserved Total
Used Total和Reserved 均是物理内存,其中Reserved是unity向系统申请的总内存,Unity底层为了不经常向系统申请开辟内存,开启了较大一块内存作为缓存,即所谓的Reserve ...
- 自定义Mybatis返回类型及注意事项
一.自定义返回拦截器package com.yaoex.crm.service.util; import org.apache.ibatis.session.ResultContext;import ...
- [Xcode 实际操作]九、实用进阶-(31)为IAP(支付方式)内购功能的具体实现和测试
目录:[Swift]Xcode实际操作 本文将演示如何为IAP(支付方式)内购功能的具体实现和测试. 内购是苹果市场上的一种常见的盈利方式. 在项目中确保已经安装了第三方库[Pod],双击[Podfi ...
- 自定义socket 模拟B/S服务端
目录 通过什么实现连接? B/S 客户端与服务端交互过程 socket server端 python代码 (静态html反馈) socket server端 python代码 (动态html反馈) 小 ...
- Apache与Tomcat的区别和联系
经常在用apache和tomcat等这些服务器,可是总感觉还是不清楚他们之间有什么关系,在用tomcat的时候总出现apache,总感到迷惑,到底谁是主谁是次,因此特意在网上查询了一些这方面的资料,总 ...
- library not found for -lXXXXX 编译问题的解决方法
喜欢交朋友的加:微信号 dwjluck2013 编译和真机调试的时候都正常 在打包的时候遇到这个问题 解决方案:pod install 重新下载就解决了 分享给遇到同类问题的小伙伴
- PHP之session
p:first-child, #write > ul:first-child, #write > ol:first-child, #write > pre:first-child, ...
- TopCoder9915(期望dp)
1.还是逆向. 2.状态是还剩红i黑j张时的期望,这样从0,0往R,B推.注意因为是逆着的,所以到了某一步发现期望为负时直接f[i][j]归零,意义是这之后(在递推中算是这之前)的都不摸了,到这就停( ...
- Codeforces Round #396 (Div. 2) D
Mahmoud wants to write a new dictionary that contains n words and relations between them. There are ...