一 死锁现象

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

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. Word2Vec小心得

    今天终于想明白了分层softmax的作用: 哈夫曼树的作用是什么??用平均最小的长度编码!编码是为了解码成信息! 神经概率语言模型:有映射层,隐藏层,输出层,假设隐藏层是300维,输出层是和单词的数量 ...

  2. C# webapi

    HttpContextBase context = (HttpContextBase)Request.Properties["MS_HttpContext"];//获取传统cont ...

  3. 多版本python的pip 升级后, pip2 pip3 与python版本失配

    mint19.2   本来pip 和 pip2 对应 python2.7   pip3对应python3.6 用源码安装了python3.7之后. 这样 版本也没问题. 但是,  用pip3.7 安装 ...

  4. A. Blackjack

    A. Blackjack time limit per test 2 seconds memory limit per test 256 megabytes input standard input ...

  5. Linux下测试CPU性能

    一.安装stress服务 1.下载stress_1.0.1.orig.tar.gz安装包 2.解压tar xvf stress_1.0.1.orig.tar.gz 3.进入解压目录执行./config ...

  6. Java 内部类、成员类、局部类、匿名类等

    Java各种称呼类详解 Java有各种各样类,内部类.嵌套类.成员类.局部类(本地类).静态类.匿名类.文件类以及这些组合起来的称呼类,成员内部类,成员匿名类,成员嵌套类,本地匿名类等,真是多的不行, ...

  7. 自动化部署脚本--linux执行sh脚本

    自动化部署脚本文件目录: 运行主程序:./install.sh #!/bin/bash SCRIPTPATH=$(cd "$(dirname "$0")"; p ...

  8. spark MLlib 概念 5: 余弦相似度(Cosine similarity)

    概述: 余弦相似度 是对两个向量相似度的描述,表现为两个向量的夹角的余弦值.当方向相同时(调度为0),余弦值为1,标识强相关:当相互垂直时(在线性代数里,两个维度垂直意味着他们相互独立),余弦值为0, ...

  9. jenkins部署java项目

    #########################################jenkins部署#################################3 一.jenkins是什么? J ...

  10. php设计模式-注册树模式

    php注册树模式 1.什么是注册树模式? 注册树模式通过将对象实例注册到全局对象树上,需要的时候将对象从全局对象树上取下来,就像小时候买糖葫芦一样,卖糖葫芦的将糖葫芦插在一个大的杆子上,人们买的时候就 ...