python多线程死锁和可重入锁的简单示例

前端之家收集整理的这篇文章主要介绍了python多线程死锁和可重入锁的简单示例前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
对python这个高级语言感兴趣的小伙伴,下面一起跟随编程之家 jb51.cc的小编两巴掌来看看吧!

死锁

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

  1. # @param python多线程编程4: 死锁和可重入锁
  2. # @author 编程之家 jb51.cc|512Pic.com
  3. # encoding: UTF-8
  4. import threading
  5. import time
  6. class MyThread(threading.Thread):
  7. def do1(self):
  8. global resA,resB
  9. if mutexA.acquire():
  10. msg = self.name+' got resA'
  11. print msg
  12. if mutexB.acquire(1):
  13. msg = self.name+' got resB'
  14. print msg
  15. mutexB.release()
  16. mutexA.release()
  17. def do2(self):
  18. global resA,resB
  19. if mutexB.acquire():
  20. msg = self.name+' got resB'
  21. print msg
  22. if mutexA.acquire(1):
  23. msg = self.name+' got resA'
  24. print msg
  25. mutexA.release()
  26. mutexB.release()
  27. def run(self):
  28. self.do1()
  29. self.do2()
  30. resA = 0
  31. resB = 0
  32. mutexA = threading.Lock()
  33. mutexB = threading.Lock()
  34. def test():
  35. for i in range(5):
  36. t = MyThread()
  37. t.start()
  38. if __name__ == '__main__':
  39. test()
  40. # End www.jb51.cc

 

执行结果:

 

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

 

此时进程已经死掉。

 

可重入锁

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

  1. # @param python多线程编程4: 死锁和可重入锁
  2. # @author 编程之家 jb51.cc|512Pic.com
  3. import threading
  4. import time
  5. class MyThread(threading.Thread):
  6. def run(self):
  7. global num
  8. time.sleep(1)
  9. if mutex.acquire(1):
  10. num = num+1
  11. msg = self.name+' set num to '+str(num)
  12. print msg
  13. mutex.acquire()
  14. mutex.release()
  15. mutex.release()
  16. num = 0
  17. mutex = threading.Lock()
  18. def test():
  19. for i in range(5):
  20. t = MyThread()
  21. t.start()
  22. if __name__ == '__main__':
  23. test()
  24. # End www.jb51.cc

 

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

  1. # @param python多线程编程4: 死锁和可重入锁
  2. # @author 编程之家 jb51.cc|512Pic.com
  3. import threading
  4. import time
  5. class MyThread(threading.Thread):
  6. def run(self):
  7. global num
  8. time.sleep(1)
  9. if mutex.acquire(1):
  10. num = num+1
  11. msg = self.name+' set num to '+str(num)
  12. print msg
  13. mutex.acquire()
  14. mutex.release()
  15. mutex.release()
  16. num = 0
  17. mutex = threading.RLock()
  18. def test():
  19. for i in range(5):
  20. t = MyThread()
  21. t.start()
  22. if __name__ == '__main__':
  23. test()
  24. # End www.jb51.cc

执行结果:

 

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

猜你在找的Python相关文章