死锁

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

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

如下代码:

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. Aizu0189 Convenient Location(多源最短路)

    https://vjudge.net/problem/Aizu-0189 题意:求某一点到其他所有点的最短路径之和,输出该点与和. 注意Floyd可以求多源最短路径,而Dijkstra只能求单源. # ...

  2. pygame-KidsCanCode系列jumpy-part10-角色动画(上)

    上一节学习如何利用spritesheet加载图片,但是player仍然是一张静态的图片,比较枯燥,我们要让它动起来! Player类,先把各种状态的图片加载起来: # 加载各种状态的图片序列 def ...

  3. Structured Exception Handling

    https://docs.microsoft.com/en-us/windows/desktop/Debug/structured-exception-handling An exception is ...

  4. 【算法随记】Canny边缘检测算法实现和优化分析。

    以前的博文大部分都写的非常详细,有很多分析过程,不过写起来确实很累人,一般一篇好的文章要整理个三四天,但是,时间越来越紧张,后续的一些算法可能就以随记的方式,把实现过程的一些比较容易出错和有价值的细节 ...

  5. MySQL优化的一些基础

    在Apache, PHP, mysql的体系架构中,MySQL对于性能的影响最大,也是关键的核心部分.对于Discuz!论坛程序也是如此,MySQL的设置是否合理优化,直接 影响到论坛的速度和承载量! ...

  6. 对Faster R-CNN的理解(1)

    目标检测是一种基于目标几何和统计特征的图像分割,最新的进展一般是通过R-CNN(基于区域的卷积神经网络)来实现的,其中最重要的方法之一是Faster R-CNN. 1. 总体结构 Faster R-C ...

  7. C# System.IO.StreamReader

    实现一个 TextReader,使其以一种特定的编码从字节流中读取字符. using System; using System.IO; class Test { public static void ...

  8. Lombok 使用攻略

    1. Lombok 简介 Lombok 可以通过简单的注解来帮助我们简化消除一些必须有但显得很臃肿的Java代码,通过使用对应的注解,可以在编译源码的时候生成对应的方法. Lombok 既是一个 ID ...

  9. 【RS】Collaborative Memory Network for Recommendation Systems - 基于协同记忆网络的推荐系统

    [论文标题]Collaborative Memory Network for Recommendation Systems    (SIGIR'18) [论文作者]—Travis Ebesu (San ...

  10. JAVA8 之 Stream sorted() 示例

    下面代码以自然序排序一个listlist.stream().sorted() 自然序逆序元素,使用Comparator 提供的reverseOrder() 方法list.stream().sorted ...