1. 首页
  2. 数据分析

python多线程编程(4): 死锁和可重入锁

python多线程编程(4): 死锁和可重入锁

死锁

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

# encoding: UTF-8 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()

python多线程编程(4): 死锁和可重入锁

执行结果:

Thread-1 got resAThread-1 got resBThread-1 got resBThread-1 got resAThread-2 got resAThread-2 got resBThread-2 got resBThread-2 got resAThread-3 got resAThread-3 got resBThread-3 got resBThread-3 got resAThread-5 got resAThread-5 got resBThread-5 got resBThread-4 got resA

此时进程已经死掉。

可重入锁

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

python多线程编程(4): 死锁和可重入锁

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多线程编程(4): 死锁和可重入锁

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

python多线程编程(4): 死锁和可重入锁

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()

python多线程编程(4): 死锁和可重入锁

执行结果:

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

转自:http://www.cnblogs.com/holbrook/archive/2012/03/08/2385449.html

精彩回顾

python多线程编程(1): python对多线程的支持

python多线程编程(2): 线程的创建、启动、挂起和退出

python多线程编程(3): 使用互斥锁同步线程

原文始发于微信公众号(PPV课数据科学社区):python多线程编程(4): 死锁和可重入锁

原创文章,作者:ppvke,如若转载,请注明出处:http://www.ppvke.com/archives/11827

联系我们

4000-51-9191

在线咨询:点击这里给我发消息

工作时间:周一至周五,9:30-18:30,节假日休息