死锁的原因及解决办法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%的程序员会选择自己百度,结果发现网友已经贴了很多类 ... 
随机推荐
- 彻底搞清楚javascript中的require、import和export
			为什么有模块概念 理想情况下,开发者只需要实现核心的业务逻辑,其他都可以加载别人已经写好的模块. 但是,Javascript不是一种模块化编程语言,在es6以前,它是不支持”类”(class),所以也 ... 
- beego orm 忽略字段
			忽略字段 设置 - 即可忽略 struct 中的字段 type User struct { ... AnyField string `orm:"-"` ... } beego or ... 
- Linux之网络编程:时间服务器
			基于TCP-服务器 1,创建一个socket套接字 int socket(int domain,int type,int protocol) domain:IP地址族,AF_INET(IPv4).AF ... 
- HTTPS IP直连问题小结
			HTTPS IP直连问题小结: https://blog.csdn.net/leelit/article/details/77829196 可以使用OkHttpClient进行相同IP地址,不同DNS ... 
- Deep Learning.ai学习笔记_第一门课_神经网络和深度学习
			目录 前言 第一周(深度学习引言) 第二周(神经网络的编程基础) 第三周(浅层神经网络) 第四周(深层神经网络) 前言 目标: 掌握神经网络的基本概念, 学习如何建立神经网络(包含一个深度神经网络), ... 
- MongoDB地理空间数据存储及检索
			目录 1.存入地理数据 GeoJSON数据存入 1.Ponit 点数据 2.LineString 线数据(多段线) 3. Polygon 多边形数据 4.MultiPoint多点.MultiLineS ... 
- PowerShe 消息提示框测试
			1. 使用powerShell 弹出一个简单的消息框,代码如下,创建test.ps1脚本文件. $ConfirmPreference = 'None' $ws = New-Object -ComObj ... 
- MySQL导出TSV格式文件
			可以使用mysqldump, 也可以使用mysql -e 使用mysqldump 因为要使用到 -T / --tab 参数, 需要先查看mysql设置的secure_file_priv mysql&g ... 
- IDC机房机器日志采集配置
			以机器 gpu-server-011 为例: 机房机器添加AliUids操作 [root@gpu-server-011 ~]# mkdir -p /etc/ilogtail/users/ [root ... 
- 阿里云 CentOS7 安装 Nginx 后,无法访问的问题
			在阿里云实例中,选择 网络与安全中的安全组.修改安全组规则. 例如: 但是还是不行 需要这样排查 netstat -anp | grep 80 iptables -L -n firewall- ... 
