Python:Lock 和 Rlock 对象之间的区别
线程是进程中可以调度执行的实体。此外,它是可以在 OS(操作系统)中执行的最小处理单元。简而言之,线程是程序中可以独立于其他代码执行的一系列此类指令。为简单起见,您可以假设线程只是进程的子集!
Refer to the below article the get the idea about threads.
- Multithreading in Python
锁具
这些是Python中最简单的同步原语。锁有两种状态,即锁定和解锁。锁是线程模块中的一个类,其对象在解锁状态下生成,并具有两个主要方法,即acquire()
和release()
。当调用 acquire() 方法时,它会锁定 Lock 的执行并阻止它的执行,直到在其他某个线程中调用 release() 方法将其设置为解锁状态。锁帮助我们有效地访问程序中的共享资源以防止数据损坏,它遵循互斥,因为一次只有一个线程可以访问特定资源。
让我们看下面的例子来了解锁的使用:
# program to illustrate the use of Locks
import threading
# creating a Lock object
lock = threading.Lock()
# initializing the shared resource
geek = 0
def sumOne():
global geek
# locking the shared resource
lock.acquire()
geek = geek + 1
# unlocking the shared resource
lock.release()
def sumTwo():
global geek
# locking the shared resource
lock.acquire()
geek = geek + 2
# unlocking the shared resource
lock.release()
# calling the functions
sumOne()
sumTwo()
# displaying the value of shared resource
print(geek)
输出:
3
在上面的程序中, lock
是一个 Lock 对象,全局变量geek
是一个共享资源,而sumOne()
和sumTwo()
函数作为线程,在sumOne()
函数中,共享资源geek
先被锁定,然后加 1 和然后释放geek
,在sumTwo()
函数中,变量geek
先被锁定,然后递增2,然后释放geek
sumOne()
和sumTwo()
这两个函数不能同时访问共享资源geek
,只能访问其中一个可以一次访问共享资源geek
。
锁
默认锁不识别锁当前持有的线程。如果任何线程正在访问共享资源,则尝试访问共享资源的其他线程将被阻止,即使它是锁定共享资源的同一线程。在这些情况下使用可重入锁或 RLock 来防止意外阻塞访问共享资源。如果共享资源在 RLock 中,则可以安全地再次调用它。 RLocked 资源可以被不同的线程重复访问,尽管它在被不同的线程调用时仍然可以正常工作。
让我们看下面的例子来了解 RLocks 的使用:
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)
在上面的程序中,两个线程试图同时访问共享资源geek
,这里当一个线程当前正在访问共享资源geek
时,另一个线程将被阻止访问它。当两个或多个线程试图访问同一个资源时,有效地阻止了彼此访问该资源,这被称为死锁,由于上述程序不产生任何输出。
但是,程序中的上述问题可以通过使用RLock来解决。
# 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)
输出:
3
在这里,程序中的线程不会阻止访问共享资源极客。我们需要为 RLock 对象锁的每个acquire()
调用一次release()
。
从上面提到的众多程序和解释中, Python中的 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. | An RLock object can be acquired numerous times by any thread. |
A Lock object can be released by any thread. | An RLock object can only be released by the thread which acquired it. |
A Lock object can be owned by none | An RLock object can be owned by many threads |
Execution of a Lock object is faster. | Execution of an RLock object is slower than a Lock object |