python死锁案例_死锁与递归锁

本文介绍了死锁的概念,通过科学家吃面问题展示了死锁现象,并使用Python的线程和锁进行示例。通过引入递归锁(RLock)解决了这个问题,但指出递归锁并未从根本上解决死锁,只是避免了特定情况下的死锁。文章还对比了互斥锁和递归锁的区别,并强调死锁本质上是逻辑错误。
摘要由CSDN通过智能技术生成

[TOC]

**多进程好多线程都有死锁的问题**

## 一 死锁现象

所谓死锁: 是指两个或两个以上的进程或线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程,

### 死锁案例-科学家吃面问题

~~~

import time

from threading import Thread,Lock

def eat1(name,fork_lock,noodle_lock):

fork_lock.acquire() #拿叉子锁

print('%s拿到叉子了'%name)

noodle_lock.acquire() #拿面条锁

print('%s拿到面条了' % name)

print('%s吃面'%name)

noodle_lock.release() #释放面条锁

fork_lock.release() #释放叉子锁

def eat2(name,fork_lock,noodle_lock):

noodle_lock.acquire()

print('%s拿到面条了' % name)

time.sleep(1)

fork_lock.acquire()

print('%s拿到叉子了' % name)

print('%s吃面'%name)

fork_lock.release()

noodle_lock.release()

fork_lock = Lock()

noodle_lock = Lock()

Thread(target=eat1,args=('alex',fork_lock,noodle_lock)).start()

Thread(target=eat2,args=('wusir',fork_lock,noodle_lock)).start()

~~~

**执行效果**

~~~

alex拿到叉子了

alex拿到面条了

alex吃面

wusir拿到面条了

yuan拿到叉子了 #出现死锁,整个程序阻塞住

~~~

## 二 递归锁

解决方法,递归锁,在Python中为了支持在同一线程中多次请求同一资源,python提供了可重入锁RLock。

这个RLock内部维护着一个Lock和一个counter变量,counter记录了acquire的次数,从而使得资源可以被多次require。直到一个线程所有的acquire都被release,其他的线程才能获得资源。

### 递归锁解决吃面问题

~~~

import time

from threading import Thread,RLock

def eat1(name,fork_lock,noodle_lock):

fork_lock.acquire()

print('%s拿到叉子了'%name)

noodle_lock.acquire()

print('%s拿到面条了' % name)

print('%s吃面'%name)

noodle_lock.release()

fork_lock.release()

def eat2(name,fork_lock,noodle_lock):

noodle_lock.acquire()

print('%s拿到面条了' % name)

time.sleep(1)

fork_lock.acquire()

print('%s拿到叉子了' % name)

print('%s吃面'%name)

fork_lock.release()

noodle_lock.release()

fork_lock =noodle_lock = RLock()

#一个线程拿到锁,counter加1,该线程内又碰到加锁的情况,则counter继续加1,

#这期间所有其他线程都只能等待,等待该线程释放所有锁,即counter递减到0为止

Thread(target=eat1,args=('alex',fork_lock,noodle_lock)).start()

Thread(target=eat2,args=('wusir',fork_lock,noodle_lock)).start()

Thread(target=eat1,args=('yuan',fork_lock,noodle_lock)).start()

~~~

执行结果:

```

alex拿到叉子了

alex拿到面条了

alex吃面

wusir拿到面条了

wusir拿到叉子了

wusir吃面

yuan拿到叉子了

yuan拿到面条了

yuan吃面

Process finished with exit code 0

```

## 互斥锁和递归锁的区别

互斥锁在同一个线程中连续acquire一次以上就会死锁

递归锁在同一个线程中可以连续的acquire多次而不发生死锁

* 普遍说法 :

递归锁可以代替互斥锁来解决死锁现象

* 实际上 :

递归锁的解决死锁实际上是牺牲了时间和空间的

**死锁从本质上来讲是一种逻辑错**

**递归锁没有从根本上解决死锁问题**

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值