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

本文共 1966 字,大约阅读时间需要 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都是以同一顺序来获取锁的,是不是造成死锁的。

你可能感兴趣的文章
Mongodb使用
查看>>
发布XWriterLib演示版,用C#写的类似word的所见即所得的文本编辑器,有演示程序的C#源代码....
查看>>
程序员面试宝典(第4版)
查看>>
Android HTML & XML 转义字符
查看>>
扩展kmp
查看>>
学习Object-C,GUNstep安装在windows上
查看>>
《Word排版艺术》读后感,兼谈LaTeX
查看>>
Service Object Model
查看>>
Javascript自动补全类(2)
查看>>
Android——监听事件OnLongClickListener
查看>>
Android——数据存储:手机内部存储
查看>>
反向代理服务器的工作原理
查看>>
idea 换行设置
查看>>
git 一个分支完全覆盖另一个分支
查看>>
【转载】星级评分--jQuery插件
查看>>
postgresql基本命令
查看>>
android如何浏览并选择图片 音频 视频
查看>>
短信息协议
查看>>
T-SQL判断是否为今天
查看>>
sping mvc 结合 hibernate 实现用户登录功能(三)!
查看>>