📜  Python:Lock 和 Rlock 对象之间的区别

📅  最后修改于: 2022-05-13 01:54:49.906000             🧑  作者: Mango

Python:Lock 和 Rlock 对象之间的区别

线程是进程中可以调度执行的实体。此外,它是可以在 OS(操作系统)中执行的最小处理单元。简而言之,线程是程序中可以独立于其他代码执行的一系列此类指令。为简单起见,您可以假设线程只是进程的子集!

锁具

这些是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 对象之间存在许多差异:

LocksRLocks
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 noneAn 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