python 防死锁机制
https://www.cnblogs.com/wongbingming/p/9035575.html
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
在编写多线程程序时,可能无意中就会写了一个死锁。可以说,死锁的形式有多种多样,但是本质都是相同的,都是对资源不合理竞争的结果。
以本人的经验总结,死锁通常以下几种
- 同一线程,嵌套获取同把锁,造成死锁。
- 多个线程,不按顺序同时获取多个锁。造成死锁
对于第一种,上面已经说过了,使用可重入锁。
主要是第二种。可能你还没明白,是如何死锁的。
举个例子。
线程1,嵌套获取A,B两个锁,线程2,嵌套获取B,A两个锁。
由于两个线程是交替执行的,是有机会遇到线程1获取到锁A,而未获取到锁B,在同一时刻,线程2获取到锁B,而未获取到锁A。由于锁B已经被线程2获取了,所以线程1就卡在了获取锁B处,由于是嵌套锁,线程1未获取并释放B,是不能释放锁A的,这是导致线程2也获取不到锁A,也卡住了。两个线程,各执一锁,各不让步。造成死锁。
经过数学证明,只要两个(或多个)线程获取嵌套锁时,按照固定顺序就能保证程序不会进入死锁状态。
那么问题就转化成如何保证这些锁是按顺序的?
有两个办法
- 人工自觉,人工识别。
- 写一个辅助函数来对锁进行排序。
第一种,就不说了。
第二种,可以参考如下代码
import threading from contextlib import contextmanager # Thread-local state to stored information on locks already acquired _local = threading.local() @contextmanager def acquire(*locks): # Sort locks by object identifier locks = sorted(locks, key=lambda x: id(x)) # Make sure lock order of previously acquired locks is not violated acquired = getattr(_local,'acquired',[]) if acquired and max(id(lock) for lock in acquired) >= id(locks[0]): raise RuntimeError('Lock Order Violation') # Acquire all of the locks acquired.extend(locks) _local.acquired = acquired try: for lock in locks: lock.acquire() yield finally: # Release locks in reverse order of acquisition for lock in reversed(locks): lock.release() del acquired[-len(locks):]
如何使用呢?
import threading x_lock = threading.Lock() y_lock = threading.Lock() def thread_1(): while True: with acquire(x_lock): with acquire(y_lock): print('Thread-1') def thread_2(): while True: with acquire(y_lock): with acquire(x_lock): print('Thread-2') t1 = threading.Thread(target=thread_1) t1.daemon = True t1.start() t2 = threading.Thread(target=thread_2) t2.daemon = True t2.start()
看到没有,表面上thread_1
的先获取锁x,再获取锁y
,而thread_2
是先获取锁y
,再获取x
。
但是实际上,acquire
函数,已经对x
,y
两个锁进行了排序。所以thread_1
,hread_2
都是以同一顺序来获取锁的,是不是造成死锁的。
python 防死锁机制的更多相关文章
- Python的GIL机制与多线程编程
GIL 全称global interpreter lock 全局解释锁 gil使得python同一个时刻只有一个线程在一个cpu上执行字节码,并且无法将多个线程映射到多个cpu上,即不能发挥多个cpu ...
- 防刷票机制研究和.NET HttpRequest Proxy
最近应朋友之约 测试他做的投票网站 防刷票机制能力如何,下面有一些心得和体会. 朋友网站用PHP写的,走的是HttpRequest,他一开始认为IP认证应该就差不多了.但说实话这种很low,手动更换代 ...
- Python GIL 多线程机制 (C source code)
最近阅读<Python源码剖析>对进程线程的封装解释: GIL,Global Interpreter Lock,对于python的多线程机制非常重要,其如何实现的?代码中实现如下: 指向一 ...
- 路由信息协议(RIP)的防环机制
防环机制 1-记数最大值(maximum hop count):定义最大跳数(最大为15跳),当跳数为16跳时,目标为不可达. 2-水平分割(split horizon):从一个接口学习到的路由不会再 ...
- python的反射机制
转载自:http://www.cnblogs.com/feixuelove1009/p/5576206.html 对编程语言比较熟悉的朋友,应该知道"反射"这个机制.Python作 ...
- python 的import机制2
http://blog.csdn.net/sirodeng/article/details/17095591 python 的import机制,以备忘: python中,每个py文件被称之为模块, ...
- 说说API的防重放机制
说说API的防重放机制 我们在设计接口的时候,最怕一个接口被用户截取用于重放攻击.重放攻击是什么呢?就是把你的请求原封不动地再发送一次,两次...n次,一般正常的请求都会通过验证进入到正常逻辑中,如果 ...
- Python垃圾回收机制 总结
Python 垃圾回收机制 内存管理 Python中的内存管理机制的层次结构提供了4层,其中最底层则是C运行的malloc和free接口,往上的三层才是由Python实现并且维护的,第一层则是在第0层 ...
- 简单谈谈python的反射机制
转:http://www.jb51.net/article/87479.htm 本文主要介绍python中的反射,以及该机制的简单应用,熟悉JAVA的程序员,一定经常和Class.forName打交道 ...
随机推荐
- DBA记录-数据库管理员需要掌握的内容
1.Linux 2.ORACLE/MySQL/SQLSERVER 3.NOSQL 4.环境部署.用户及权限管理.表空间.表.视图.索引.过程.触发器.分区.函数.查询.性能调优.迁移备份.集群.日志分 ...
- 关于同步,异步,阻塞,非阻塞,IOCP/epoll,select/poll,AIO ,NIO ,BIO的总结
相关资料 IO基本概念 Linux环境 同步异步阻塞非阻塞 同步与异步 阻塞与非阻塞 IO模型Reference Link 阻塞IO模型 非阻塞IO模型 IO复用模型 信号驱动异步IO模型 异步IO模 ...
- Java EE 之 Hibernate异常总结【4】org.hibernate.exception.SQLGrammarException: could not execute statement
本质原因:配置的Java Bean,由Hibernate自动产生的SQL语句中有语法错误 原因如下: 情况1.存在字段名/表名与数据库关键字冲突 情况2.MySQL5.0以后与MySQL5.0以前事务 ...
- luogu P4036 [JSOI2008]火星人
传送门 很久以前xzz大佬就喊我做这题,结果现在才做qwq 因为要在序列中插入,所以直接用\(Splay\)维护这个串的哈希值,插入就直接把那个点插♂进去,修改就把点旋到根,然后修改和pushup,询 ...
- C#中富文本编辑器Simditor带图片上传的全部过程(MVC架构的项目)
描述:最近c#项目中使用富文本编辑器Simditor,记录一下以便以后查看. 注:此项目是MVC架构的. 1.引用文件 项目中引用相应的css和js文件,注意顺序不能打乱,否则富文本编辑器不会正常显示 ...
- weblogic中部署SSH项目遇到的坑
总结将SSH项目部署到weblogic遇到的坑.项目中是SSH,另外还用到了webservice.quartz等框架.在tomcat部署是可以的,现在总结部署到weblogic遇到的坑. 在这里说一下 ...
- 【转】Zabbix 3.0 从入门到精通(zabbix使用详解)
[转]Zabbix 3.0 从入门到精通(zabbix使用详解) 第1章 zabbix监控 1.1 为什么要监控 在需要的时刻,提前提醒我们服务器出问题了 当出问题之后,可以找到问题的根源 网站/ ...
- Linux中THIS_MODULE宏定义详解
一直都在耿耿于怀,这个THIS_MODULE到底是个什么玩意,linux内核中无处不在的东西.今天上网搜了一下,算是基本明白了.网上牛人写的已经比较详细,另外目前暂时没有时间往更深层次分析,所以直接贴 ...
- Python3学习笔记08-tuple
元组与列表类似,不同之处在于元组的元素不能修改 元组使用小括号,列表使用方括号 元组创建很简单,只需要在括号中添加元素,并使用逗号隔开即可 tup1 = ('Google', 'Runoob', 19 ...
- Windows 10 的一些快捷键
Win键 + Q: 呼出[Cortana] Win键 + W:呼出[Windows INNK 工作区] Win键 + E: 呼出[资源管理器] Win键 + R: 呼出[运行] Win键 + A: 呼 ...