如果多个线程共同对某个数据修改,则可能出现不可预料的结果,为了保证数据的正确性,需要对多个线程进行同步,使用 Thread 对象的 Lock 和 Rlock 可以实现简单的线程同步,这两个对象都有 acquire 方法和 release 方法,分别用来获取和释放锁 启动3个线程对count进行操作
import threading count = 0 def print_time(threadName): global count c = 0 while(c<100): c+=1 count +=1 print("{0}:set count to {1}".format(threadName,count)) try: threading.Thread( target=print_time, args=("Thread-1", ) ).start() threading.Thread( target=print_time, args=("Thread-2", ) ).start() threading.Thread( target=print_time, args=("Thread-3", ) ).start() except Exception as e: print("Error: unable to start thread")
结果“ 每个thread对count进行改动期间while(c<100)
,有其它的thread插入进来改动count
通过threading.Lock() 实现,通过Lock的acquire()和release()函数
来控制加锁和解锁,使用简单得方法 with实现
import threading lock = threading.Lock() count = 0 def print_time(threadName): global count c = 0 with lock: while(c<100): c+=1 count +=1 print("{0}:set count to {1}".format(threadName,count)) try: threading.Thread( target=print_time, args=("Thread-1", ) ).start() threading.Thread( target=print_time, args=("Thread-2", ) ).start() threading.Thread( target=print_time, args=("Thread-3", ) ).start() except Exception as e: print("Error: unable to start thread")
结果
通过threading.Rlock() 实现
import threading rlock = threading.RLock() count = 0 def print_time(threadName): global count c = 0 with rlock: while(c<100): c+=1 count +=1 print("{0}:set count to {1}".format(threadName,count)) try: threading.Thread( target=print_time, args=("Thread-1", ) ).start() threading.Thread( target=print_time, args=("Thread-2", ) ).start() threading.Thread( target=print_time, args=("Thread-3", ) ).start() except Exception as e: print("Error: unable to start thread")
j结果
Lock和Rlock的区别
import threading lock = threading.Lock() #Lock对象 lock.acquire() lock.acquire() #产生了死琐。 lock.release() lock.release()
import threading lock = threading.RLock() #Lock对象 lock.acquire() lock.acquire() 程序不会堵塞 lock.release() lock.release()
Locks | RLocks |
---|---|
A Lock object can not be acquired again by any thread unless it is released by the thread which which is accessing the shared resource. 一个lock被释放前不能被其他线程获得acquire |
An RLock object can be acquired numerous times by any thread. 一个Rlock可以被其他任意线程获得 |
A Lock object can be released by any thread. 一个lock可以被其他线程释放 |
An RLock object can only be released by the thread which acquired it. Rlock只能被获得他的线程释放 |
A Lock object can be owned by one lock被一个线程占有 |
An RLock object can be owned by many threads Rlock可以被其他线程获得 |
Execution of a Lock object is faster. lock的运行速度快 |
Execution of an RLock object is slower than a Lock object 运行速度比lock慢 |
这两种琐的主要区别是:RLock允许在同一线程中被多次acquire。而Lock却不允许这种情况
。注意:如果使用RLock
,那么acquire和release必须成对出现
,即调用了n次acquire,必须调用n次的release才能真正释放所占用的琐