美文网首页
死锁和可重入锁

死锁和可重入锁

作者: lkning | 来源:发表于2018-05-25 11:52 被阅读0次

死锁

在线程间共享多个资源的时候,如果两个线程分别占有一部分资源并且同时等待对方的资源,就会造成死锁。尽管死锁很少发生,但一旦发生就会造成应用的停止响应。下面看一个死锁的例子:

import threading
import time

class MyThread(threading.Thread):
    def do1(self):
        global resA, resB
        if mutexA.acquire():
             msg = self.name+' got resA'
             print msg

             if mutexB.acquire(1):
                 msg = self.name+' got resB'
                 print msg
                 mutexB.release()
             mutexA.release()
    def do2(self):
        global resA, resB
        if mutexB.acquire():
             msg = self.name+' got resB'
             print msg

             if mutexA.acquire(1):
                 msg = self.name+' got resA'
                 print msg
                 mutexA.release()
             mutexB.release()

    def run(self):
        self.do1()
        self.do2()
resA = 0
resB = 0

mutexA = threading.Lock()
mutexB = threading.Lock()

def test():
    for i in range(5):
        t = MyThread()
        t.start()
if __name__ == '__main__':
    test()

执行结果:

> Thread-1 got resA
> Thread-1 got resB
> Thread-1 got resB
> Thread-1 got resA
> Thread-2 got resA
> Thread-2 got resB
> Thread-2 got resB
> Thread-2 got resA
> Thread-3 got resA
> Thread-3 got resB
> Thread-3 got resB
> Thread-3 got resA
> Thread-5 got resA
> Thread-5 got resB
> Thread-5 got resB
> Thread-4 got resA

此时进程已经死掉。

可重入锁

更简单的死锁情况是一个线程“迭代”请求同一个资源,直接就会造成死锁:

import threading
import time

class MyThread(threading.Thread):
    def run(self):
        global num 
        time.sleep(1)

        if mutex.acquire(1):  
            num = num+1
            msg = self.name+' set num to '+str(num)
            print msg
            mutex.acquire()
            mutex.release()
            mutex.release()
num = 0
mutex = threading.Lock()
def test():
    for i in range(5):
        t = MyThread()
        t.start()
if __name__ == '__main__':
    test()

为了支持在同一线程中多次请求同一资源,python提供了“可重入锁”:threading.RLock。RLock内部维护着一个Lock和一个counter变量,counter记录了acquire的次数,从而使得资源可以被多次require。直到一个线程所有的acquire都被release,其他的线程才能获得资源。上面的例子如果使用RLock代替Lock,则不会发生死锁:

import threading
import time

class MyThread(threading.Thread):
    def run(self):
        global num 
        time.sleep(1)

        if mutex.acquire(1):  
            num = num+1
            msg = self.name+' set num to '+str(num)
            print msg
            mutex.acquire()
            mutex.release()
            mutex.release()
num = 0
mutex = threading.RLock()
def test():
    for i in range(5):
        t = MyThread()
        t.start()
if __name__ == '__main__':
    test()

执行结果:

> Thread-1 set num to 1
> Thread-3 set num to 2
> Thread-2 set num to 3
> Thread-5 set num to 4
> Thread-4 set num to 5

相关文章

  • 死锁和可重入锁

    死锁 在线程间共享多个资源的时候,如果两个线程分别占有一部分资源并且同时等待对方的资源,就会造成死锁。尽管死锁很少...

  • 锁-Lock-04

    可重入锁广义上的可重入锁指的是可重复可递归调用的锁,在外层使用锁之后,在内层仍然可以使用,并且不发生死锁(前提得是...

  • 并发 :线程间同步、锁、可重入锁及互斥锁

    线程间同步 线程间同步涉及线程互斥锁; 锁(Lock)容易导致死锁,可重入锁(RLock)则不会导致死锁,但每次 ...

  • 谈谈Python线程中的“锁机制”

    何为Lock( 锁 )?如何使用Lock( 锁 )?为何要使用锁?可重入锁(RLock)防止死锁的加锁机制饱受争议...

  • Java 可重入锁 公平锁 读写锁

    1.可重入锁 如果锁具备可重入性,则称作为可重入锁。 像synchronized和ReentrantLock都是可...

  • 可重入锁和非可重入锁

    1 可重入锁 (ReentrantLock和synchronized)可重入锁指的是可重复可递归调用的锁,在外层使...

  • 多线程8实现重入锁

    非重入锁 计数 线程无限期等待示例 重入锁,类似于sychronized,不会有死锁情况

  • J.U.C-AQS-ReentrantLock

    ReentrantLock(可重入锁)和synchronized区别 可重入性 锁的实现(ReentrantLoc...

  • 重入锁 Condition 读写锁 适用于读多写少场景 死锁

  • Java中的各种锁

    一个线程中的多个流程能不能获取同一把锁:可重入锁和非可重入锁 可重入锁 可重入性:表明了锁的分配机制,是基于线程的...

网友评论

      本文标题:死锁和可重入锁

      本文链接:https://www.haomeiwen.com/subject/jhvyjftx.html