详解Python中的Lock和Rlock

作者:abce 时间:2023-08-11 18:35:20 

线程是进程中可以调度执行的实体。而且,它是操作系统中可以执行的最小处理单元。简单地说,一个线程就是一个程序中可以独立于其他代码执行的指令序列。为了简单起见,你可以假设线程只是进程的子集!

Locks

锁是Python中用于同步的最简单的方式。锁有两种状态:上锁、释放锁。

锁是线程模块中的一个类,有两个主要方法:acquire()和release() 当调用acquire()方法时,它锁定锁的执行并阻塞锁的执行,直到其他线程调用release()方法将其设置为解锁状态。锁帮助我们有效地访问程序中的共享资源,以防止数据损坏,它遵循互斥,因为一次只能有一个线程访问特定的资源。

让我们看看下面的例子来理解锁的使用:


import threading
 
#创建一个lock对象
lock = threading.Lock()
 
#初始化共享资源
abce = 0
 
def sumOne():
    global abce
 
    #锁定共享资源
    lock.acquire()
    abce = abce + 1
 
    #释放共享资源
    lock.release()
 
def sumTwo():
    global abce
 
    #锁定共享资源
    lock.acquire()
    abce = abce + 2
 
    #释放共享资源
    lock.release()
 
#调用函数
 
sumOne()
sumTwo()
print(abce)

在上面的程序中,lock是一个锁对象,全局变量abce是一个共享资源,sumOne()和sumTwo()函数扮作两个线程,在sumOne()函数中共享资源abce首先被锁定,然后增加了1,然后abce被释放。sumTwo()函数执行类似操作。 两个函数sumOne()和sumTwo()不能同时访问共享资源abce,一次只能一个访问共享资源。

RLocks

默认的lock不能识别lock当前被哪个线程持有。如果任何线程正在访问共享资源,那么试图访问共享资源的其他线程将被阻塞,即使锁定共享资源的线程也是如此。 在这些情况下,可重入锁(或RLock)用于防止访问共享资源时出现不必要的阻塞。如果共享资源在RLock中,那么可以安全地再次调用它。 RLocked资源可以被不同的线程重复访问,即使它在被不同的线程调用时仍然可以正常工作。

让我们看看下面的例子来理解RLocks的使用:


import threading
 
#创建一个lock对象
lock = threading.Lock()
 
#初始化共享资源
abce = 0
 
#本线程访问共享资源
lock.acquire()
abce = abce + 1
 
#这个线程访问共享资源会被阻塞
lock.acquire()
abce = abce + 2
lock.release()
 
print(abce)

在上面的程序中,两个线程同时尝试访问共享资源abce,这里当一个线程当前正在访问共享资源abce时,另一个线程将被阻止访问它。 当两个或多个线程试图访问相同的资源时,有效地阻止了彼此访问该资源,这就是所谓的死锁,因此上述程序没有生成任何输出。

但是,在程序中上述问题可以通过使用RLock来解决。


import threading
 
#创建一个rlock对象
lock = threading.RLock()
 
#初始化共享资源
abce = 0
 
#本线程访问共享资源
lock.acquire()
abce = abce + 1
 
#这个线程尝试访问共享资源
lock.acquire()
abce = abce + 2
lock.release()
 
print(abce)

在这里,没有阻止程序中的线程访问共享资源abce。 对于RLock对象锁的每个acquire(),我们需要调用release()一次。

从上面提到的众多程序和解释中,在Python中一个Lock对象和一个RLock对象有很多区别:

locksrlocks
lock对象无法再被其他线程获取,除非持有线程释放rlock对象可以被其他线程多次获取
lock对象可被任何线程释放rlock对象只能被持有的线程释放
lock对象不可以被任何线程拥有rlock对象可以被多个线程拥有
对一个对象锁定是很快的对一个对象加rlock比加lock慢

来源:https://www.cnblogs.com/abclife/p/13196044.html

标签:python,lock,rlock
0
投稿

猜你喜欢

  • JS使用ajax从xml文件动态获取数据显示的方法

    2024-04-19 10:06:36
  • asp测字符串长度及截取定长字符串汉字的处理

    2007-10-12 13:14:00
  • 利用脚本自动安装SQLServer的实现步骤分析

    2024-01-22 20:02:11
  • CentOS+Nginx+PHP+MySQL详细配置(图解)

    2023-11-24 03:04:13
  • 详解Python中最难理解的点-装饰器

    2023-02-14 04:51:59
  • 用实例说明python的*args和**kwargs用法

    2021-05-04 08:25:55
  • 如何在SQL Server 2005数据库中导入SQL Server 2008的数据

    2024-01-27 22:05:21
  • Python爬虫框架Scrapy实战之批量抓取招聘信息

    2022-03-28 11:38:09
  • python 用递归实现通用爬虫解析器

    2022-04-15 08:13:55
  • 流行WEB开发语言比较之ASP篇

    2007-12-23 17:23:00
  • 如何在pycharm中配置pyqt5设计GUI操作教程

    2021-09-28 17:42:21
  • Python3 虚拟开发环境搭建过程(图文详解)

    2021-11-19 00:34:51
  • 使用 Angular 服务器端渲染 Transfer State Service

    2024-04-22 22:39:50
  • 一文搞懂Python中subprocess模块的使用

    2023-12-05 16:35:05
  • python使用两种发邮件的方式smtp和outlook示例

    2021-02-12 13:31:54
  • Python Pandas对缺失值的处理方法

    2021-03-18 19:38:55
  • 用Python写一个模拟qq聊天小程序的代码实例

    2022-04-01 10:01:42
  • Python中requests做接口测试的方法

    2022-04-10 11:06:18
  • 简单了解Python3里的一些新特性

    2022-09-22 21:32:23
  • Python中Django框架下的staticfiles使用简介

    2022-08-18 14:04:40
  • asp之家 网络编程 m.aspxhome.com