线程锁
线程锁真的好麻烦啊!!!
找了几篇博客发现写的都不一样 相关联内容太多不容易理解
所以现在需要理清
- 什么是线程锁
- 应用场景
- 怎么用
- 优缺点
1. 什么是线程锁机制
多线程可以同时运行多个任务
但是当多个线程同时访问共享数据时,可能导致数据不同步,甚至错误!
so,不使用线程锁, 可能导致错误
啰嗦两句: 比如你在银行取钱的同时你女朋友用支付宝取钱 不同线程同时访问同一资源 如果资源不加锁可能会导致银行亏本 卡里有100却取出200这种错误
2. 应用场景
I/O密集型操作 需要资源保持同步
3.用法
#锁的使用
#创建锁
lock = threading.Lock()
#锁定
lock.acquire([timeout])
#释放
lock.release()
example
import threading
import time
counter = 0
counter_lock = threading.Lock() #只是定义一个锁,并不是给资源加锁,你可以定义多个锁,像下两行代码,当你需要占用这个资源时,任何一个锁都可以锁这个资源
counter_lock2 = threading.Lock()
counter_lock3 = threading.Lock()
#可以使用上边三个锁的任何一个来锁定资源
class MyThread(threading.Thread):#使用类定义thread,继承threading.Thread
def __init__(self,name):
threading.Thread.__init__(self)
self.name = "Thread-" + str(name)
def run(self): #run函数必须实现
global counter,counter_lock #多线程是共享资源的,使用全局变量
time.sleep(1);
if counter_lock.acquire(): #当需要独占counter资源时,必须先锁定,这个锁可以是任意的一个锁,可以使用上边定义的3个锁中的任意一个
counter += 1
print "I am %s, set counter:%s" % (self.name,counter)
counter_lock.release() #使用完counter资源必须要将这个锁打开,让其他线程使用
if __name__ == "__main__":
for i in xrange(1,101):
my_thread = MyThread(i)
my_thread.start()
4.优缺点
优点:保证资源同步
缺点:有等待肯定会慢
5.扩展(死锁与递归锁)
如果多个线程要调用多个对象,而A线程调用A锁占用了A对象,B线程调用了B锁占用了B对象,A线程不能调用B对象,B线程不能调用A对象,于是一直等待。这就造成了线程“死锁”。
Threading模块中,也有一个类,RLock,称之为可重入锁。该锁对象内部维护着一个Lock和一个counter对象。counter对象记录了acquire的次数,使得资源可以被多次require。最后,当所有RLock被release后,其他线程才能获取资源。在同一个线程中,RLock.acquire可以被多次调用,利用该特性,可以解决部分死锁问题。
就是把 lock=threading.Lock()改成lock = threading.RLock()