一 死锁现象

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

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. IDEA创建spring加struts2项目

    选择spring和struts,注意版本,不同的struts版本,过滤器的位置不一样 选择存放位置,并点击完成创建项目,在创建过程中会自动下载相关jar 初始化完成后的目录结构为 修复生成的web.x ...

  2. 28. ClustrixDB 分布式架构/评估模型

    本节描述如何在数据库中计算查询.在ClustrixDB中,我们跨节点切片数据,然后将查询发送到数据.这是数据库的基本原则之一,它允许随着添加更多节点而几乎线性地扩展. 有关如何分布数据的概念,请参阅数 ...

  3. jquery dblclick()方法 语法

    jquery dblclick()方法 语法 作用:当双击元素时,会发生 dblclick 事件.当鼠标指针停留在元素上方,然后按下并松开鼠标左键时,就会发生一次 click.在很短的时间内发生两次 ...

  4. codevs 1009 产生数x

                         题目描述 Description 给出一个整数 n(n<10^30) 和 k 个变换规则(k<=15). 规则: 一位数可变换成另一个一位数: 规 ...

  5. hash索引

    hash算法 哈希表(hash table ,也叫散列表),是根据关键码值(key value)而直接进行访问的数据结构.也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度.这个 ...

  6. AtCoder AGC037D Sorting a Grid (二分图匹配)

    题目链接 https://atcoder.jp/contests/agc037/tasks/agc037_d 题解 这场D题终于不像AGC032D和AGC036D一样神仙了-- 还是可做的吧 虽然考场 ...

  7. 工具类-ApplicationContextUtil

    package com.zhouyy.netBank.util; import org.springframework.beans.BeansException; import org.springf ...

  8. kali VMWOOLS的安装

    别人的教程 https://jingyan.baidu.com/article/3ea51489992f1f52e71bba45.html

  9. sqli-libs(3)

    今天我们来讲解 sqli-libs(3) 有括号的单引号报错  首先我们来查看加入'看报错了 在加‘’ 没报错 证明 存在注入 然后我们看加入’的报错回显的是什么 和我们的sqli-libs(1)的报 ...

  10. 如何将JS中object转换为字符串

    var obj = JSON.parse(str); //由JSON字符串转换为JSON对象 var last=obj.toJSONString(); //将JSON对象转化为JSON字符 或者 va ...