From: http://www.cnblogs.com/holbrook/archive/2012/03/08/2385449.html

在线程间共享多个资源的时候,如果两个线程分别占有一部分资源并且同时等待对方的资源,就会造成死锁。尽管死锁很少发生,但一旦发生就会造成应用的停止响应。下面看一个死锁的例子:

# encoding: UTF-8import threadingimport time

class MyThread(threading.Thread):    def do1(self):        global resA, resB        if mutexA.acquire():             msg = self.name+' got resA'             print msg

             if mutexB.acquire(1):                 msg = self.name+' got resB'                 print msg                 mutexB.release()             mutexA.release()    def do2(self):        global resA, resB        if mutexB.acquire():             msg = self.name+' got resB'             print msg

             if mutexA.acquire(1):                 msg = self.name+' got resA'                 print msg                 mutexA.release()             mutexB.release()

    def run(self):        self.do1()        self.do2()resA = 0resB = 0

mutexA = threading.Lock()mutexB = threading.Lock()

def test():    for i in range(5):        t = MyThread()        t.start()if __name__ == '__main__':    test()

执行结果:

Thread-1 got resA
Thread-1 got resB
Thread-1 got resB
Thread-1 got resA
Thread-2 got resA
Thread-2 got resB
Thread-2 got resB
Thread-2 got resA
Thread-3 got resA
Thread-3 got resB
Thread-3 got resB
Thread-3 got resA
Thread-5 got resA
Thread-5 got resB
Thread-5 got resB
Thread-4 got resA

此时进程已经死掉。

可重入锁

更简单的死锁情况是一个线程“迭代”请求同一个资源,直接就会造成死锁:

import threadingimport time

class MyThread(threading.Thread):    def run(self):        global num         time.sleep(1)

        if mutex.acquire(1):              num = num+1            msg = self.name+' set num to '+str(num)            print msg            mutex.acquire()            mutex.release()            mutex.release()num = 0mutex = threading.Lock()def test():    for i in range(5):        t = MyThread()        t.start()if __name__ == '__main__':    test()

为了支持在同一线程中多次请求同一资源,python提供了“可重入锁”:threading.RLock。RLock内部维护着一个Lock和一个counter变量,counter记录了acquire的次数,从而使得资源可以被多次require。直到一个线程所有的acquire都被release,其他的线程才能获得资源。上面的例子如果使用RLock代替Lock,则不会发生死锁:

import threadingimport time

class MyThread(threading.Thread):    def run(self):        global num         time.sleep(1)

        if mutex.acquire(1):              num = num+1            msg = self.name+' set num to '+str(num)            print msg            mutex.acquire()            mutex.release()            mutex.release()num = 0mutex = threading.RLock()def test():    for i in range(5):        t = MyThread()        t.start()if __name__ == '__main__':    test()

执行结果:

Thread-1 set num to 1
Thread-3 set num to 2
Thread-2 set num to 3
Thread-5 set num to 4
Thread-4 set num to 5

python多线程编程(4): 死锁和可重入锁相关推荐

  1. python threading lock_python threading之死锁和可重入锁

    一.死锁 简单来说,死锁是一个资源被多次调用,而多次调用方都未能释放该资源就会造成死锁,这里结合例子说明下两种常见的死锁情况. 1.迭代死锁 该情况是一个线程"迭代"请求同一个资源 ...

  2. 并发编程-19AQS同步组件之重入锁ReentrantLock、 读写锁ReentrantReadWriteLock、Condition

    文章目录 J.U.C脑图 ReentrantLock概述 ReentrantLock 常用方法 synchronized 和 ReentrantLock的比较 ReentrantLock示例 读写锁R ...

  3. java代码如何避免死锁,Java可重入锁如何避免死锁

    看到一个问题,Java的可重入锁为什么可以防止死锁呢?网上看了看资料,虽然有答案说出了正确答案,但是分析的不够详细,对初学者不够友好.这里我再做一个更清晰的分析. 首先是示例代码: 1 public ...

  4. Java高并发编程(六):重入锁

    重入锁定义:重入锁ReentrantLock,就是支持重进入的锁,它表示该锁能够支持一个线程对资源的重复加锁.除此之外,该锁的还支持获取锁时的公平和非公平性选择. ReentrantLock虽然没能像 ...

  5. 【python第三方库】python多线程编程---threading库

    文章目录 一.python多线程 1. GIL 二.threading库使用介绍 1. 创建多线程 2. 线程合并 3. 线程同步与互斥锁Lock 4. 死锁与可重入锁(递归锁)RLock 5. 守护 ...

  6. Java多线程系列——深入重入锁ReentrantLock

    简述 ReentrantLock 是一个可重入的互斥(/独占)锁,又称为"独占锁". ReentrantLock通过自定义队列同步器(AQS-AbstractQueuedSychr ...

  7. java中多线程reentlock_Java多线程系列——深入重入锁ReentrantLock

    简述 ReentrantLock 是一个可重入的互斥(/独占)锁,又称为"独占锁". ReentrantLock通过自定义队列同步器(AQS-AbstractQueuedSychr ...

  8. Java中的锁机制 -- 乐观锁、悲观锁、自旋锁、可重入锁、读写锁、公平锁、非公平锁、共享锁、独占锁、重量级锁、轻量级锁、偏向锁、分段锁、互斥锁、同步锁、死锁、锁粗化、锁消除

    文章目录 1. Java中的锁机制 1.1 乐观锁 1.2 悲观锁 1.3 自旋锁 1.4 可重入锁(递归锁) 1.5 读写锁 1.6 公平锁 1.7 非公平锁 1.8 共享锁 1.9 独占锁 1.1 ...

  9. Java 中15种锁的介绍:公平锁,可重入锁,独享锁,互斥锁,乐观锁,分段锁,自旋锁等等...

    http://blog.51cto.com/13919357/2339446 Java 中15种锁的介绍 在读很多并发文章中,会提及各种各样锁如公平锁,乐观锁等等,这篇文章介绍各种锁的分类.介绍的内容 ...

最新文章

  1. Matlab与数据结构 -- 如何获取给定目录中的文件
  2. Python 中名词
  3. oracle每一行的hash值,Hash分区表分区数与数据分布的测试
  4. [Shder]物体溶解效果
  5. 1020 月饼 (25分)
  6. localhost 已拒绝连接_【Python】MongoDB数据库的连接和操作
  7. qt中QList使用removeAt()删除元素
  8. 低版本系统兼容的ActionBar(六)用Fragment+ViewPager+Tab实现快速导航
  9. centos7 ifconfig命令找不到_Linux基础命令大全,你找不到的这都有
  10. C++数字与字符串的相互转换
  11. 超级烧脑惊悚悬疑电影《恐怖游轮》(原片+解说)
  12. 计算机网络物理层之数据通信的基础知识
  13. 开源字体下载——思源黑体
  14. HP服务器清除bios方法
  15. java方法重载[详解]
  16. photoshop去眼袋
  17. 打印当前python文件出错行
  18. 小程序做电商的硬伤 “正规军”入驻 草根望尘莫及
  19. 【可见光室内定位】(二)基于光电器件PD的可见光室内定位技术
  20. 【Linux】权限管理

热门文章

  1. iframe中的历史记录问题汇总及解决方案[转]
  2. 缔造完美运维 共谱双赢新篇
  3. 你如何摆平秋季问题皮肤
  4. python对象引用计数器_在Python中借助计数器对象对项目进行计数
  5. mysql程序设计教程_MySQL教程_编程入门教程_牛客网
  6. redis将散裂中某个值自增_这些Redis命令你都掌握了没?
  7. leetcode 5786. 可移除字符的最大数目(二分法)
  8. 初探Golang(2)-常量和命名规范
  9. leetcode 73. 矩阵置零
  10. nsa构架_我如何使用NSA的Ghidra解决了一个简单的CrackMe挑战