死锁的原因及解决办法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) # 让睡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递归锁的更多相关文章
- SQL Server死锁产生原因及解决办法 .
其实所有的死锁最深层的原因就是一个:资源竞争 表现一: 一个用户A 访问表A(锁住了表A),然后又访问表B,另一个用户B 访问表B(锁住了表B),然后企图访问表A,这时用户A由于用户B已经锁住表B,它 ...
- Oracle死锁产生的原因和解决办法
如果有两个会话,每个会话都持有另一个会话想要的资源,此时就会发生死锁.用下面实验来说明死锁的产生原因和解决办法.SESSION1:SQL> create table t2 as select * ...
- mysql数据库死锁的产生原因及解决办法
这篇文章主要介绍了mysql数据库锁的产生原因及解决办法,需要的朋友可以参考下 数据库和操作系统一样,是一个多用户使用的共享资源.当多个用户并发地存取数据 时,在数据库中就会产生多个事务同时存取同 ...
- HttpClient的CircularRedirectException异常原因及解决办法
HttpClient的CircularRedirectException异常原因及解决办法 这两天在使用我自己爬虫抓取网页的时候总是出现 org.apache.http.client.ClientPr ...
- jquery ajax success 函数 异步调用方法中不能给全局变量赋值的原因及解决办法
jquery ajax success 函数 异步调用方法中不能给全局变量赋值的原因及解决办法 在调用一个jquery的ajax方法时我们有时会需要该方法返回一个值或者给某个全局变量赋值,可是我们 ...
- 各种编码问题产生原因以及解决办法---------响应编码,请求编码,URL编码
响应编码 产生原因以及解决办法: 示例: package cn.yzu; import java.io.IOException; import javax.servlet.ServletExcept ...
- .Net内存泄露原因及解决办法
.Net内存泄露原因及解决办法 1. 什么是.Net内存泄露 (1).NET 应用程序中的内存 您大概已经知道,.NET 应用程序中要使用多种类型的内存,包括:堆栈.非托管堆和托管堆.这里我们需 ...
- php_curl.dll libssh2.dll 始终无法加载的原因 及解决办法
在StackOverflow得到最终原因及解决办法 http://stackoverflow.com/questions/16424117/php-unable-to-load-php-curl-dl ...
- mysql保存中文乱码的原因和解决办法
当你遇到这个mysql保存中文乱码问题的时候,期待找到mysql保存中文乱码的原因和解决办法这样一篇能解决问题的文章是多么激动人心. 也许30%的程序员会选择自己百度,结果发现网友已经贴了很多类 ...
随机推荐
- .ipynb格式文件
ipynb,即ipython notebook,需要用ipython notebook打开,IPython Notebook是web based IPython封装,但是可以展现富文本,使得整个工作可 ...
- linux 系统下使用socket进行本地进程间通信
转自:https://blog.csdn.net/baidu_24553027/article/details/54912724 使用套接字除了可以实现网络间不同主机间的通信外,还可以实现同一主机的不 ...
- Css3 实现循环留言滚动效果(一)
一.常见留言滚动效果示例 html代码 <div class="runList"> <div class="runitem"> < ...
- 【性能提升神器】STRAIGHT_JOIN
今天给大家下另一个性能提升神器-STRAIGHT_JOIN,在数据量大的联表查询中灵活运用的话,能大大缩短查询时间. 首先来解释下STRAIGHT_JOIN到底是用做什么的: STRAIGHT_JOI ...
- hive sql 里面的注释方式
如果建表ddl 用 comment 这个没问题 那么在sql 语句里面呢,这个貌似不像mysql 那样能用 # // /* */ (左边这些都不行) 其实用 -- comment 就行啦 貌似上面的- ...
- 如何将excel 数据库表结构生成powerdesign物理模型
Option Explicit Dim mdl ' the current model Set mdl = ActiveModel If (mdl Is Nothing) Then MsgBox &q ...
- SpringDataJpa学习
# SpringBoot Jdbc JPA JPA是`Java Persistence API`的简称,中文名Java持久层API,是JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的 ...
- flink 有状态udf 引起血案一
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/rlnLo2pNEfx9c/article/details/83422587 场景 近期在做一个画像的 ...
- 获得最近一天的提交,并使用winscp上传到服务器
@echo off D:\dev\Git\bin\git.exe pull origin master D:\dev\Git\bin\git.exe add -A D:\dev\Git\bin\git ...
- 如何修改启动jupyter的文件路径
1.cmd 2.jupyter notebook 工作目录路径 办法二: 1.启动pycharm 2.创建一个ipynb文件 3.运行该文件---在打印结果中找到网址,在网页中打开即可正常显示