lock与Rlock的区别
1、lock与Rlock的区别
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()
操作,程序不会阻塞。
=========================
eg1: 死锁
import threading # initializing the shared resource geek = 0 # creating a Lock object lock = threading.Lock() # the below thread is accessing the # shared resource lock.acquire() geek = geek + 1 # This thread will be blocked lock.acquire() geek = geek + 2 lock.release() # displaying the value of shared resource print(geek)
----output--无数据输出
eg2--OK:# program to illustrate the use of RLocks # importing the module import threading # initializing the shared resource geek = 0 # creating an RLock object instead # of Lock object lock = threading.RLock() # the below thread is trying to access # the shared resource lock.acquire() geek = geek + 1 # the below thread is trying to access # the shared resource lock.acquire() geek = geek + 2 lock.release() lock.release() # displaying the value of shared resource print(geek)
output =3
=================
“lock = threading.Lock()”,这就是最普通的Lock;还有一种RLock锁,使用“lock = threading.RLock()”即可。
其实RLock和Lock很像,几乎一样,唯一的区别是RLock中可以继续上RLock锁,但是Lock锁不能这样做,Lock锁一旦这样做了,线程就会卡死。示例如下:
# coding=utf-8 import threading # 定义RLock锁 lock = threading.RLock() def fuck( thread_name ): lock.acquire() # 上锁 ... lock.acquire() # 上锁 !!! 假设定义的不是RLock,而是Lock,那在这里机会卡死 ... lock.release() # 解锁 ... lock.release() # 解锁 threading.Thread( target=fuck, args=("fuck-1", ) ).start() threading.Thread( target=fuck, args=("fuck-2", ) ).start() threading.Thread( target=fuck, args=("fuck-3", ) ).start()
上述的示例如果换成with lock的方式,如下:
# coding=utf-8 import threading # 定义RLock锁 lock = threading.RLock() def fuck( thread_name ): with lock: ... with lock: # !!! 假设定义的不是RLock,而是Lock,那在这里机会卡死 ... threading.Thread( target=fuck, args=("fuck-1", ) ).start() threading.Thread( target=fuck, args=("fuck-2", ) ).start() threading.Thread( target=fuck, args=("fuck-3", ) ).start()
上述两个示例程序中,假设最初定义的不是RLock,而是Lock,那在示例代码中打叹号注释的位置直接卡死。
这时就会有人问道,为啥要在上锁状态中继续上锁呢?这不是傻X嘛?
原因:假如这是一个很复杂的多线程程序呢?比如函数中要使用一堆别的函数,届时,在不同的函数中就很有可能需要对某段代码要上锁,这时RLock的价值就体现了。
综上:对于简单的多线程代码使用Lock即可,对于复杂的多线程系统,优先使用RLock。