详解Python中的Lock和Rlock


Posted in Python onJanuary 26, 2021

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

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对象有很多区别:

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

以上就是详解Python中的Lock和Rlock的详细内容,更多关于Python中Lock和Rlock的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
python爬虫入门教程之糗百图片爬虫代码分享
Sep 02 Python
Python中使用插入排序算法的简单分析与代码示例
May 04 Python
numpy中的高维数组转置实例
Apr 17 Python
Python设计模式之备忘录模式原理与用法详解
Jan 15 Python
如何使用Python进行OCR识别图片中的文字
Apr 01 Python
Python脚本利用adb进行手机控制的方法
Jul 08 Python
face++与python实现人脸识别签到(考勤)功能
Aug 28 Python
Macbook安装Python最新版本、GUI开发环境、图像处理、视频处理环境详解
Feb 17 Python
解决tensorflow/keras时出现数组维度不匹配问题
Jun 29 Python
Python如何在bool函数中取值
Sep 21 Python
通过Python pyecharts输出保存图片代码实例
Nov 25 Python
python uuid生成唯一id或str的最简单案例
Jan 13 Python
5分钟快速掌握Python定时任务框架的实现
Jan 26 #Python
Python爬虫自动化爬取b站实时弹幕实例方法
Jan 26 #Python
python 实现的车牌识别项目
Jan 25 #Python
Python实现给PDF添加水印的方法
Jan 25 #Python
2021年值得向Python开发者推荐的VS Code扩展插件
Jan 25 #Python
numba提升python运行速度的实例方法
Jan 25 #Python
python中K-means算法基础知识点
Jan 25 #Python
You might like
php DOS攻击实现代码(附如何防范)
2012/05/29 PHP
PHP采集静态页面并把页面css,img,js保存的方法
2014/12/23 PHP
Laravel路由设定和子路由设定实例分析
2016/03/30 PHP
laravel 框架结合关联查询 when()用法分析
2019/11/22 PHP
修改发贴的编辑功能
2007/03/07 Javascript
JavaScript学习笔记之获取当前目录的实现代码
2010/12/14 Javascript
Javascript延迟执行实现方法(setTimeout)
2010/12/30 Javascript
JsDom 编程小结
2011/08/09 Javascript
js中的scroll和offset 使用比较的实例与分析
2013/09/29 Javascript
jquery中常用的函数和属性详细解析
2014/03/07 Javascript
jQuery 复合选择器应用的几个例子
2014/09/11 Javascript
JavaScript构造函数详解
2015/12/27 Javascript
复杂的javascript窗口分帧解析
2016/02/19 Javascript
使用jQuery5分钟快速搞定双色表格的简单实例
2016/08/08 Javascript
javascript 实现动态侧边栏实例详解
2016/11/11 Javascript
使用nodejs下载风景壁纸
2017/02/05 NodeJs
原生JS实现简单放大镜效果
2017/02/08 Javascript
写jQuery插件时的注意点
2017/02/20 Javascript
分享一个精简的vue.js 图片lazyload插件实例
2017/03/13 Javascript
ES5学习教程之Array对象
2017/04/01 Javascript
解决vue js IOS H5focus无法自动弹出键盘的问题
2018/08/30 Javascript
vue将后台数据时间戳转换成日期格式
2019/07/31 Javascript
使用setup.py安装python包和卸载python包的方法
2013/11/27 Python
Python转换HTML到Text纯文本的方法
2015/01/15 Python
在Python中用split()方法分割字符串的使用介绍
2015/05/20 Python
python 全文检索引擎详解
2017/04/25 Python
python中class的定义及使用教程
2019/09/18 Python
Python虚拟环境venv用法详解
2020/05/25 Python
日本索尼音乐商店:Sony Music Shop
2018/07/17 全球购物
澳大利亚墨尔本的在线时装店:LORETA
2018/09/14 全球购物
斐乐美国官方网站:FILA美国
2019/03/01 全球购物
Nike瑞士官网:Nike CH
2021/01/18 全球购物
用C#语言写出在本地创建一个UDP接收端口的具体过程
2016/02/22 面试题
家长会主持词开场白
2015/05/29 职场文书
浅谈Web Storage API的使用
2021/06/23 Javascript
JavaScript展开运算符和剩余运算符的区别详解
2022/02/18 Javascript