死锁

说到死锁,可以讲一个科学家吃面的问题:

有几个科学家在一张桌子旁,桌子上只有一把筷子和一碗面,我们将面和筷子都加锁。这是可能会导致一个科学家抢到面,另一个科学家抢到筷子,这是就全部阻塞了,这就是死锁了。

如下代码:

from threading import Thread, Lock, RLock
import time # 这个函数,先让拿筷子,再拿面条,
def eat1(args, Chopsticks_lock, Noodles_lock):
Chopsticks_lock.acquire() # 拿钥匙
print('%s拿到了筷子'%args)
Noodles_lock.acquire() # 拿钥匙
print('%s拿到了面条'%args)
print('%s吃到了面条'%args)
Noodles_lock.release() # 还钥匙
Chopsticks_lock.release() # 还钥匙 # 这个函数,先让那面条,再让拿筷子。
def eat2(args, Chopsticks_lock, Noodles_lock):
Noodles_lock.acquire()
print('%s拿到了面条' % args)
time.sleep(0.1) # 让睡0.1面,这样更容易,一个线程拿到面条,一个线程拿到筷子,出现阻塞,出现死锁。
Chopsticks_lock.acquire()
print('%s拿到了筷子'%args)
print('%s吃到了面条'%args)
Noodles_lock.release()
Chopsticks_lock.release() # 创建两个锁,分别给面条和筷子加锁。
Chopsticks_lock = Lock()
Noodles_lock = Lock()
Thread(target=eat1, args=('小明', Chopsticks_lock, Noodles_lock)).start()
Thread(target=eat2, args=('小红', Chopsticks_lock, Noodles_lock)).start()
Thread(target=eat1, args=('小兰', Chopsticks_lock, Noodles_lock)).start()
Thread(target=eat2, args=('小军', Chopsticks_lock, Noodles_lock)).start()

打印结果:

小明拿到了筷子
小明拿到了面条
小明吃到了面条
小红拿到了面条
小兰拿到了筷子

看到小红拿到了面条,而小兰拿到了筷子,他们都需要对方拿到的资源来完成吃面条的整个过程,但是线程未使用完资源之前,不可被剥夺,并且线程拿不到需要的资源就会阻塞,就造成了死锁的情况。

如何解决?

引入递归锁。

递归锁RLock

from threading import Thread, Lock, RLock
import time def eat1(args, Chopsticks_lock, Noodles_lock):
Chopsticks_lock.acquire()
print('%s拿到了筷子'%args)
Noodles_lock.acquire()
print('%s拿到了面条'%args)
print('%s吃到了面条'%args)
Noodles_lock.release()
Chopsticks_lock.release() def eat2(args, Chopsticks_lock, Noodles_lock):
Noodles_lock.acquire()
print('%s拿到了面条' % args)
time.sleep(0.1)
Chopsticks_lock.acquire()
print('%s拿到了筷子'%args)
print('%s吃到了面条'%args)
Noodles_lock.release()
Chopsticks_lock.release() Chopsticks_lock = Noodles_lock = RLock() Thread(target=eat1, args=('小明', Chopsticks_lock, Noodles_lock)).start()
Thread(target=eat2, args=('小红', Chopsticks_lock, Noodles_lock)).start()
Thread(target=eat1, args=('小兰', Chopsticks_lock, Noodles_lock)).start()
Thread(target=eat2, args=('小军', Chopsticks_lock, Noodles_lock)).start()

打印结果:

小明拿到了筷子
小明拿到了面条
小明吃到了面条
小红拿到了面条
小红拿到了筷子
小红吃到了面条
小兰拿到了筷子
小兰拿到了面条
小兰吃到了面条
小军拿到了面条
小军拿到了筷子
小军吃到了面条

值得注意的是,线程锁Lock是互斥锁,只有一把钥匙。而递归锁RLock是一个钥匙串的很多把钥匙,每个钥匙都可以开一把锁,但是只要一个进程拿到这串钥匙的其中一个钥匙,其他线程就拿不到钥匙了,这就是递归锁,就造成不了面条和筷子分别被两个线程拿到的情况了。

结束!

死锁的原因及解决办法RLock递归锁的更多相关文章

  1. SQL Server死锁产生原因及解决办法 .

    其实所有的死锁最深层的原因就是一个:资源竞争 表现一: 一个用户A 访问表A(锁住了表A),然后又访问表B,另一个用户B 访问表B(锁住了表B),然后企图访问表A,这时用户A由于用户B已经锁住表B,它 ...

  2. Oracle死锁产生的原因和解决办法

    如果有两个会话,每个会话都持有另一个会话想要的资源,此时就会发生死锁.用下面实验来说明死锁的产生原因和解决办法.SESSION1:SQL> create table t2 as select * ...

  3. mysql数据库死锁的产生原因及解决办法

    这篇文章主要介绍了mysql数据库锁的产生原因及解决办法,需要的朋友可以参考下   数据库和操作系统一样,是一个多用户使用的共享资源.当多个用户并发地存取数据 时,在数据库中就会产生多个事务同时存取同 ...

  4. HttpClient的CircularRedirectException异常原因及解决办法

    HttpClient的CircularRedirectException异常原因及解决办法 这两天在使用我自己爬虫抓取网页的时候总是出现 org.apache.http.client.ClientPr ...

  5. jquery ajax success 函数 异步调用方法中不能给全局变量赋值的原因及解决办法

    jquery ajax success 函数 异步调用方法中不能给全局变量赋值的原因及解决办法   在调用一个jquery的ajax方法时我们有时会需要该方法返回一个值或者给某个全局变量赋值,可是我们 ...

  6. 各种编码问题产生原因以及解决办法---------响应编码,请求编码,URL编码

     响应编码 产生原因以及解决办法: 示例: package cn.yzu; import java.io.IOException; import javax.servlet.ServletExcept ...

  7. .Net内存泄露原因及解决办法

    .Net内存泄露原因及解决办法 1.    什么是.Net内存泄露 (1).NET 应用程序中的内存 您大概已经知道,.NET 应用程序中要使用多种类型的内存,包括:堆栈.非托管堆和托管堆.这里我们需 ...

  8. php_curl.dll libssh2.dll 始终无法加载的原因 及解决办法

    在StackOverflow得到最终原因及解决办法 http://stackoverflow.com/questions/16424117/php-unable-to-load-php-curl-dl ...

  9. mysql保存中文乱码的原因和解决办法

    当你遇到这个mysql保存中文乱码问题的时候,期待找到mysql保存中文乱码的原因和解决办法这样一篇能解决问题的文章是多么激动人心.    也许30%的程序员会选择自己百度,结果发现网友已经贴了很多类 ...

随机推荐

  1. RESTEASY ,从学会使用到了解原理。

    转载本文需注明出处:EAII企业架构创新研究院,违者必究.如需加入微信群参与微课堂.架构设计与讨论直播请直接回复公众号:“EAII企业架构创新研究院”.(微信号:eaworld) 1,背景知识; 1. ...

  2. 尚未备份数据库 "***" 的日志尾部。如果该日志包含您不希望丢失的工作,请使用 BACKUP LOG WITH NORECOVERY 备份该日志。

    使用SQL Server 2005还原备份的数据库文件时出现的问题,如题. 前提:如果你有个数据库的.bak的备份文件. 右键点击 数据库任务-->还原-->数据库 1.还原的目标选择你要 ...

  3. Multiple Tasks Z

    public static async Task executeParallel<T>(this IEnumerable<T> items, int limit, Func&l ...

  4. .net core安装及初体验

    .net core安装及初体验 .net core 作为微软的新一代技术,在开发跨平台.微服务等方面有很大的优势,也更贴近现代的编码习惯.在2.0版发布很久以后,近期终于决定进行学习和体验. 安装 作 ...

  5. ConditionalOnProperty

    配置Spring Boot通过@ConditionalOnProperty来控制Configuration是否生效 1.matchIfMissing属性:从application.properties ...

  6. IIS Express ArgumentOutOfRangeException

    重装了VS,调试网站,IIS Express 打开时遇到如下错误. “/”应用程序中的服务器错误. 指定的参数已超出有效值的范围.参数名: site 说明: 执行当前 Web 请求期间,出现未经处理的 ...

  7. Data type conversion in MongoDB

    [问题] I have a collection called Document in MongoDB. Documents in this collection have a field calle ...

  8. golang 使用pprof和go-torch做性能分析

    软件开发过程中,项目上线并不是终点.上线后,还要对程序的取样分析运行情况,并重构现有的功能,让程序执行更高效更稳写. golang的工具包内自带pprof功能,使找出程序中占内存和CPU较多的部分功能 ...

  9. 【Inno Setup】添加许可协议,并默认选中我同意按钮

      [Setup] ; xkfile.txt文件不能为空 LicenseFile=C:\Documents and Settings\Administrator\桌面\smqh\xkfile.txt ...

  10. 异类查询要求为连接设置ANSI_NULLS和ANSI_WARNINGS选项

    在查询分析器中,先输入两句    set   ansi_nulls   on    set   ansi_warnings   on    执行然后再    Create   Proc   存储过程  ...