博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
python 防死锁机制
阅读量:4460 次
发布时间:2019-06-08

本文共 2017 字,大约阅读时间需要 6 分钟。

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 threadingfrom contextlib import contextmanager# Thread-local state to stored information on locks already acquired_local = threading.local()@contextmanagerdef 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 threadingx_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 = Truet1.start()t2 = threading.Thread(target=thread_2)t2.daemon = Truet2.start()

 

 

看到没有,表面上thread_1的先获取锁x,再获取锁y,而thread_2是先获取锁y,再获取x

但是实际上,acquire函数,已经对xy两个锁进行了排序。所以thread_1hread_2都是以同一顺序来获取锁的,是不是造成死锁的。

转载于:https://www.cnblogs.com/aguncn/p/10179635.html

你可能感兴趣的文章
51Nod 1596 搬货物
查看>>
java 中方法的重写
查看>>
idea中git标签(tag)的创建与使用
查看>>
jQuery Easing酷炫动画效果展示Demo
查看>>
回到学校的第六天
查看>>
系统监控 磁盘分区
查看>>
自定义Form组件
查看>>
Apollo配置中心源码分析
查看>>
MySql编码、卸载、启动问题
查看>>
模式匹配
查看>>
Codeforces Looksery Cup 2015
查看>>
ArcGIS10中找不到ESRI.ArcGIS.Utility引用的解决方案
查看>>
也来玩玩canvas
查看>>
递归实现排列组合
查看>>
微众银行面试小总结
查看>>
.net 添加序号
查看>>
storm1.0节点间消息传递过久分析及调优
查看>>
java命令行指定log4j2
查看>>
用心整理的 献丑啦 一些关于http url qs fs ...模块的方法
查看>>
[Python学习] python 科学计算库NumPy—矩阵运算
查看>>