python多线程编程(4): 死锁和可重入锁
2015-08-05 15:31
716 查看
原文转载自:http://www.cnblogs.com/holbrook/archive/2012/03/08/2385449.html
死锁
在线程间共享多个资源的时候,如果两个线程分别占有一部分资源并且同时等待对方的资源,就会造成死锁。尽管死锁很少发生,但一旦发生就会造成应用的停止响应。下面看一个死锁的例子:# 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()
执行结果:
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
此时进程已经死掉。==== 》原因在于,Thread-5 需要资源resA变量,而Thread-4需要资源resB变量。导致的死锁。
可重入锁
更简单的死锁情况是一个线程“迭代”请求同一个资源,直接就会造成死锁: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
相关文章推荐
- python下安装lxml
- python 爬虫 爬下图片
- python中类方法和静态方法
- Python学习笔记02
- Python3 win7安装BeautifulSoup
- Python快速教程博客园地址
- 南邮 OJ 1387 Pythons
- Python 爬虫
- python 的常用时间操作
- Python Paramiko模块安装和使用
- Python 学习笔记01
- python curses使用
- How-to: resolve spark "/usr/bin/python: No module named pyspark" issue
- PYTHON之批量文件指定字符串替换
- Python学习之数字
- 数据专家必知必会的 7 款 Python 工具
- python的with是如何工作的
- python __name__
- python code
- python:解析html(HTMLParser、SGMLParser)