一 死锁现象

所谓死锁: 是指两个或两个以上的进程或线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程,如下就是死锁

from threading import Thread
from threading import Lock
import time # 实例化两把不同的锁
mutexA = Lock()
mutexB = Lock() class MyThread(Thread): def run(self):
self.f1()
self.f2() def f1(self):
mutexA.acquire()
print("%s拿到A锁" % self.name) # Thread类自带name属性 mutexB.acquire()
print("%s拿到B锁" % self.name)
mutexB.release() mutexA.release() def f2(self):
mutexB.acquire()
print("%s拿到B锁" % self.name) # Thread类自带name属性
time.sleep(0.1)
mutexA.acquire() print("%s拿到A锁" % self.name)
mutexA.release() mutexB.release() if __name__ == "__main__":
for i in range(1,11):
t = MyThread()
t.start()

执行结果

Thread-1拿到A锁
Thread-1拿到B锁
Thread-1拿到B锁
Thread-2拿到A锁 # 出现死锁,整个程序卡住

解决方法:

二 递归锁

递归锁,在Python中为了支持在同一线程中多次请求同一资源,python提供了可重入锁RLock。

这个RLock内部维护着一个Lock和一个counter变量,counter记录了acquire的次数,从而使得资源可以被多次require。直到一个线程所有的acquire都被release,其他的线程才能获得资源。

上面的例子如果使用RLock代替Lock,则不会发生死锁,

二者的区别是:

递归锁可以连续acquire多次,每acquire一次计数器加1,

只要计数不为0,就不能被其他线程抢到。只有计数为0时,才能被其他线程抢到acquire。释放一次计数器-1

而互斥锁只能加锁acquire一次,想要再加锁acquire,就需要release解之前的锁

from threading import Thread
from threading import RLock
import time # 实例化一把锁,mutexA 和mutexB公用一把锁
mutexB = mutexA = RLock() class MyThread(Thread): def run(self):
self.f1()
self.f2() def f1(self):
mutexA.acquire()
print("%s拿到A锁" % self.name) # Thread类自带name属性 mutexB.acquire()
print("%s拿到B锁" % self.name)
mutexB.release() mutexA.release() def f2(self):
mutexB.acquire()
print("%s拿到B锁" % self.name) # Thread类自带name属性
time.sleep(0.1)
mutexA.acquire() print("%s拿到A锁" % self.name)
mutexA.release() mutexB.release() if __name__ == "__main__":
for i in range(1,5):
t = MyThread()
t.start()
'''
Thread-1拿到A锁
Thread-1拿到B锁
Thread-1拿到B锁
Thread-1拿到A锁
Thread-2拿到A锁
Thread-2拿到B锁
Thread-2拿到B锁
Thread-2拿到A锁
Thread-4拿到A锁
Thread-4拿到B锁
Thread-4拿到B锁
Thread-4拿到A锁
Thread-3拿到A锁
Thread-3拿到B锁
Thread-3拿到B锁
Thread-3拿到A锁
Thread-5拿到A锁
Thread-5拿到B锁
Thread-5拿到B锁
Thread-5拿到A锁
'''

python 并发编程 多线程 死锁现象与递归锁的更多相关文章

  1. Python并发编程05 /死锁现象、递归锁、信号量、GIL锁、计算密集型/IO密集型效率验证、进程池/线程池

    Python并发编程05 /死锁现象.递归锁.信号量.GIL锁.计算密集型/IO密集型效率验证.进程池/线程池 目录 Python并发编程05 /死锁现象.递归锁.信号量.GIL锁.计算密集型/IO密 ...

  2. 并发编程-线程-死锁现象-GIL全局锁-线程池

    一堆锁 死锁现象 (重点) 死锁指的是某个资源被占用后,一直得不到释放,导致其他需要这个资源的线程进入阻塞状态. 产生死锁的情况 对同一把互斥锁加了多次 一个共享资源,要访问必须同时具备多把锁,但是这 ...

  3. python 并发编程 多线程 目录

    线程理论 python 并发编程 多线程 开启线程的两种方式 python 并发编程 多线程与多进程的区别 python 并发编程 多线程 Thread对象的其他属性或方法 python 并发编程 多 ...

  4. python 之 并发编程(守护线程与守护进程的区别、线程互斥锁、死锁现象与递归锁、信号量、GIL全局解释器锁)

    9.94 守护线程与守护进程的区别 1.对主进程来说,运行完毕指的是主进程代码运行完毕2.对主线程来说,运行完毕指的是主线程所在的进程内所有非守护线程统统运行完毕,主线程才算运行完毕​详细解释:1.主 ...

  5. 并发编程~~~多线程~~~守护线程, 互斥锁, 死锁现象与递归锁, 信号量 (Semaphore), GIL全局解释器锁

    一 守护线程 from threading import Thread import time def foo(): print(123) time.sleep(1) print('end123') ...

  6. 并发编程(五)--GIL、死锁现象与递归锁、信号量、Event事件、线程queue

    一.GIL全局解释器锁 1.什么是全局解释器锁 GIL本质就是一把互斥锁,相当于执行权限,每个进程内都会存在一把GIL,同一进程内的多个线程,必须抢到GIL之后才能使用Cpython解释器来执行自己的 ...

  7. 并发编程(五)——GIL全局解释器锁、死锁现象与递归锁、信号量、Event事件、线程queue

    GIL.死锁现象与递归锁.信号量.Event事件.线程queue 一.GIL全局解释器锁 1.什么是全局解释器锁 GIL本质就是一把互斥锁,相当于执行权限,每个进程内都会存在一把GIL,同一进程内的多 ...

  8. python并发编程&多线程(二)

    前导理论知识见:python并发编程&多线程(一) 一 threading模块介绍 multiprocess模块的完全模仿了threading模块的接口,二者在使用层面,有很大的相似性 官网链 ...

  9. python并发编程&多线程(一)

    本篇理论居多,实际操作见:  python并发编程&多线程(二) 一 什么是线程 在传统操作系统中,每个进程有一个地址空间,而且默认就有一个控制线程 线程顾名思义,就是一条流水线工作的过程,一 ...

随机推荐

  1. Python 面向对象Ⅳ

    类的继承 面向对象的编程带来的主要好处之一是代码的重用,实现这种重用的方法之一是通过继承机制. 通过继承创建的新类称为子类或派生类,被继承的类称为基类.父类或超类. 继承语法 在python中继承中的 ...

  2. QT:QSS完全无效的原因

    QSS的文件格式不是UTF-8,导致读取到的文件中字符串出现乱码.

  3. UVa 1595 Symmetry (set && math)

    题意:给出n个在直角坐标系上的点,问你能不能找出一条竖轴(即垂直于x的轴)使得所有的点根据这条轴对称,能则输出YES,否则输出NO 分析:首先需要找到对称轴的值,将所有n个点的x轴的值加起来然后去除以 ...

  4. TTTTTTTTTTT hdu 1520 Anniversary party 生日party 树形dp第一题

    Anniversary party Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others ...

  5. 【UOJ #46】 【清华集训2014】玄学

    题目描述 巨酱有 n 副耳机,他把它们摆成了一列,并且由 1 到n依次编号.每个耳机有一个玄学值,反映了各自的一些不可名状的独特性能.玄学值都是 0 到 m-1 间的整数.在外界的作用下(包括但不限于 ...

  6. Jmeter(一) 安装

    一.检查JDK版本 执行cmd > java -version 查看本机JDK版本,JDK版本不能低于1.6 二.软件下载 登录Jmeter官网:https://jmeter.apache.or ...

  7. 关键字transient是干啥的

    百度百科的解释: Java语言的关键字,变量修饰符,如果用transient声明一个实例变量,当对象存储时,它的值不需要维持.换句话来说就是,用transient关键字标记的成员变量不参与序列化过程. ...

  8. [翻译]剖析C#中的异步方法

    翻译自一篇博文,原文:Dissecting the async methods in C# 有些括号里的是译注或我自己的理解. 异步系列 剖析C#中的异步方法 扩展C#中的异步方法 C#中异步方法的性 ...

  9. eclipse中解决update maven之后jre被改成1.5的问题

    1.在项目的pom.xml中加入下面的代码就能解决(加入插件) <build> <plugins> <plugin> <groupId>org.apac ...

  10. mosquitto订阅发布参数详解

    特别提示:本人博客部分有参考网络其他博客,但均是本人亲手编写过并验证通过.如发现博客有错误,请及时提出以免误导其他人,谢谢!欢迎转载,但记得标明文章出处:http://www.cnblogs.com/ ...