资源总是有限的,程序运行如果对同一个对象进行操作,则有可能造成资源的争用,甚至导致死锁,或者导致读写混乱,python中提供线程锁对线程的调用进行控制
锁提供如下方法:
1.Lock.acquire([blocking])
2.Lock.release() 把
3.threading.Lock() 加载线程的锁对象,是一个基本的锁对象,一次只能一个锁定,其余锁请求,需等待锁释放后才能获取
4.threading.RLock() 多重锁,在同一线程中可用被多次acquire。如果使用RLock,那么acquire和release必须成对出现,
调用了n次acquire锁请求,则必须调用n次的release才能在线程中释放锁对象
lock实例
import threading import time counter = 0 counter_lock = threading.Lock() #只是定义一个锁,可以定义多个锁,需要的时候,任意一个锁可以锁定资源 counter_lock2 = threading.Lock() counter_lock3 = threading.Lock() #可以使用上边三个锁的任何一个来锁定资源 class MyTestThread(threading.Thread):#使用类定义thread,继承threading.Thread def __init__(self,name): threading.Thread.__init__(self) self.name = "Thread-" + str(name) def run(self): #重写run函数,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资源必须要将这个锁打开,让其他线程使用 ,lock与release必须成对出现 if __name__ == "__main__": for i in range(1,101): my_thread = MyThread(i) my_thread.start()
通过先建立一个lock锁,在线程的run()方法中,使用lock锁定全局变量,这时候使得此全局变量只会被当前线程使用和修改,不会出现多个线程同时修改一个变量的情况,在该线程运行完成之后,release释放同步锁,使得其他的线程可以竞争该全局变量,从而保证了全局变量的安全性。
在threading模块中还有一个RLOCK类,称之为可重入锁。该锁对象内部维护着一个Lock和一个counter对象。counter对象记录了acquire的次数,使得资源可以被多次require。最后,当所有RLock被release后,其他线程才能获取资源。在同一个线程中,RLock.acquire可以被多次调用,利用该特性,可以解决部分死锁问题。