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才能真正释放所占用的琐。

最新文章

  1. Travis CI用来持续集成你的项目
  2. Windbg Extension NetExt 使用指南 【3】 ---- 挖掘你想要的数据 Managed Heap
  3. 如何监控ORACLE索引使用与否
  4. 使用cocos2d-x c++ Android静态库
  5. Optimizely:在线网站A/B测试平台
  6. Control Flow
  7. Babelfish(poj 2503)
  8. postgresql压力测试工具用法以及参数解读
  9. [置顶] Android学习系列-把文件保存到SD卡上面(6)
  10. django第二个项目--使用模板
  11. mybatis结合redis实战二级缓存(六)
  12. hdu2389二分图之Hopcroft Karp算法
  13. webpack2进阶之多文件,DLL,以及webpack-merge
  14. IOS学习5——属性与成员变量
  15. RocketMQ-广播模式消费
  16. 安卓开发:初识Android Studio
  17. react-native 打包成apk 文件
  18. WPF参考
  19. BGP - 5,BGP属性
  20. AD RMS企业文件版权管理

热门文章

  1. SpringCloud之旅第一篇-微服务概念
  2. ZOJ3228【AC自动机】
  3. KING_Unity学习之UGUI_Canvas渲染顺序以及层次关系总结
  4. jzoj5984. 【北大2019冬令营模拟2019.1.1】仙人掌 (分块)
  5. IT兄弟连 JavaWeb教程 JSP中的三大指令
  6. CentOS(6、7)修改主机名(hostname)
  7. js实现打印正三角
  8. centos 无界面 服务器 安装chrome部署chromedriver
  9. __str__,__repr__,__format__
  10. Arch Linux 安装记(安装到移动硬盘)