Python中threading模块 lock、Rlock的使用

Python threading模块多种锁实现线程同步 简介 线程同步——这是一个很常见的面试题,那么实现线程同步有哪些方式呢?百度一下可以搜出很多相关文章,例如加锁,条件控制,信号量控制等等。那么Python提供了哪些方式呢?我们下面来看看。 目录 简介 目录 正文 基本锁Lock 关键方法: 样例展示: 源码分析: 递归锁RLock 关键方法: 样例展示: 源码分析: 条件锁 关键方法: 样例展示: 源码分析: 信号锁 关键方法: 样例展示: 源码分析: 阻塞锁 关键方法: 样例展示: 源码分析:... 阅读详情

一、概述

在使用多线程的应用下,如何保证线程安全,以及线程之间的同步,或者访问共享变量等问题是十分棘手的问题,也是使用多线程下面临的问题,如果处理不好,会带来较严重的后果,使用python多线程中提供Lock 、Rlock 、Semaphore 、Event 、Condition 用来保证线程之间的同步,后者保证访问共享变量的互斥问题。

  • Lock & RLock:互斥锁,用来保证多线程访问共享变量的问题
  • Semaphore对象:Lock互斥锁的加强版,可以被多个线程同时拥有,而Lock只能被某一个线程同时拥有。
  • Event对象:它是线程间通信的方式,相当于信号,一个线程可以给另外一个线程发送信号后让其执行操作。
  • Condition对象:其可以在某些事件触发或者达到特定的条件后才处理数据
1、Lock(互斥锁)

请求锁定 — 进入锁定池等待 — — 获取锁 — 已锁定— — 释放锁

Lock(指令锁)是可用的最低级的同步指令。Lock处于锁定状态时,不被特定的线程拥有。Lock包含两种状态——锁定和非锁定,以及两个基本的方法。
可以认为Lock有一个锁定池,当线程请求锁定时,将线程至于池中,直到获得锁定后出池。池中的线程处于状态图中的同步阻塞状态。

构造方法:mylock = Threading.Lock( )

实例方法:

  • acquire([timeout]): 使线程进入同步阻塞状态,尝试获得锁定。
  • release(): 释放锁。使用前线程必须已获得锁定,否则将抛出异常。

实例一(未使用锁):

import threading
import time

num = 0

def show(arg):
    global num
    time.sleep(1)
    num +=1
    print('bb :{}'.format(num))

for i in range(5):
    t = threading.Thread(target=show, args=(i,))  # 注意传入参数后一定要有【,】逗号
    t.start()

print('main thread stop')

--------------------------------------------------------------------------
main thread stop
bb :1
bb :2
bb :3bb :4
bb :5

实例二(使用锁)

import threading
import time

num = 0

lock = threading.RLock()


# 调用acquire([timeout])时,线程将一直阻塞,
# 直到获得锁定或者直到timeout秒后(timeout参数可选)。
# 返回是否获得锁。
def Func():
    lock.acquire()
    global num
    num += 1
    time.sleep(1)
    print(num)
    lock.release()


for i in range(10):
    t = threading.Thread(target=Func)
    t.start()
------------------------------------------------------------------
1
2
3
4
5
6
7
8
9
10
#可以看出,全局变量在在每次被调用时都要获得锁,才能操作,因此保证了共享数据的安全性

对于Lock对象而言,如果一个线程连续两次release,使得线程死锁。所以Lock不常用,一般采用Rlock进行线程锁的设定。

import threading
import time

class MyThread(threading.Thread):
    def run(self):
        global num 
        time.sleep(1)

        if lock.acquire(1):  
            num = num+1
            msg = self.name+' set num to '+str(num)
            print(msg)
            lock.acquire()
            lock.release()
            lock.release()
num = 0
lock = threading.Lock()
def test():
    for i in range(5):
        t = MyThread()
        t.start()
if __name__ == '__main__':
    test()
------------------------------------------------------
Thread-12 set num to 1
2、RLock(可重入锁)

RLock(可重入锁)是一个可以被同一个线程请求多次的同步指令。RLock使用了“拥有的线程”和“递归等级”的概念,处于锁定状态时,RLock被某个线程拥有。拥有RLock的线程可以再次调用acquire(),释放锁时需要调用release()相同次数。可以认为RLock包含一个锁定池和一个初始值为0的计数器,每次成功调用 acquire()/release(),计数器将+1/-1,为0时锁处于未锁定状态。

  • 构造方法:mylock = Threading.RLock()

  • 实例方法:acquire([timeout])/release(): 跟Lock差不多。

实例解决死锁,调用相同次数的acquire和release,保证成对出现

import threading
rLock = threading.RLock()  #RLock对象
rLock.acquire()
rLock.acquire() #在同一线程内,程序不会堵塞。
rLock.release()
rLock.release()

print(rLock.acquire())

详细实例:

import threading
mylock = threading.RLock()
num = 0
class WorkThread(threading.Thread):
    def __init__(self, name):
        threading.Thread.__init__(self)
        self.t_name = name
    def run(self):
        global num
        while True:
            mylock.acquire()
            print('\n%s locked, number: %d' % (self.t_name, num))
            if num >= 2:
                mylock.release()
                print('\n%s released, number: %d' % (self.t_name, num))
                break
            num += 1
            print('\n%s released, number: %d' % (self.t_name, num))
            mylock.release()
def test(): #Python小白学习交流群:711312441
    thread1 = WorkThread('A-Worker')
    thread2 = WorkThread('B-Worker')
    thread1.start()
    thread2.start()
if __name__ == '__main__':
    test() 
--------------------------------------------------
A-Worker locked, number: 0

A-Worker released, number: 1

A-Worker locked, number: 1

A-Worker released, number: 2

A-Worker locked, number: 2

A-Worker released, number: 2

B-Worker locked, number: 2

B-Worker released, number: 2
Python 多线程编程(二):threading 模块中 Lock 类的用法详解 在前面一篇博文《Python多线程编程(一):threading 模块 Thread 类的用法详解 》 我有简单介绍怎么利用 threading 模块进行多线程的编码。 但那只是多线程编码最简单的部分,真正难的其实是多个线程之间的通信和数据同步。 大概可以这样讲,多线程最难的是如何正确协调各个线程修改同一份数据。 以卖票的例子作为说明。 买票有多个窗口,假设有 3 个好了,窗口之间共享一个票池,每... 阅读详情

相关推荐

Python 中的重入锁(RLock)详解

在多线程和多进程编程中,同步机制是确保数据一致性和线程安全的关键。重入锁(Reentrant Lock),又称递归锁,是一种特殊的锁,允许同一个线程多次获取同一把锁。本文将详细介绍重入锁的原理,并提供一个简单的 Python 实现,同时对比线程和进程的概念。

Wayne_zzx1112233的博客 873

分布式锁:Redisson源码解析——RLock(一)

分布式锁——Redisson源码篇-加锁(一)初始化锁对象RLock的整体类图CommandAsyncExecutor加锁——ReentrantLock方法重载第一次加锁及watchdog续约重点设计连接发送数据结构watchdog阻塞思考 其实代码整体上可以发现实现可重入锁的方法还是比较简单的,学习成本相对比较低,使用起来也是比较简单的,对于分析可重入锁的部分从下面几个部分来大致的阅读 初始化锁对象 RLock lock = redisson.getLock("anyLock"); RLock的整体类图

weixin_47246944的博客 6507

python学习笔记之使用threading模块实现多线程

综述 Python这门解释性语言也有专门的线程模型,Python虚拟机使用GIL(Global Interpreter Lock,全局解释器锁)来互斥线程对共享资源的访问,但暂时无法利用多处理器的优势。 在Python中我们主要是通过thread和 threading这两个模块来实现的,其中Python的threading模块是对thread做了一些包装的,可以更加方便的被使用,所以我们使用 threading模块实现多线程编程。这篇文章我们主要来看看Python对多线程编程的支持。 在语言层面,..

A_Kaka的博客 685

Python | 线程锁 | 5分钟掌握【同步锁】(Threading.Lock)

`threading.Lock` 同步锁,可以用于保证多个线程对共享数据的独占访问。 当多个线程或进程互相竞争同一组资源时,如果每个线程都持有一些资源,并且都在等待另一个线程释放它所需要的资源时,就会发生死锁。死锁的产生原因通常是由于多个线程对共享资源的竞争,同时又没有良好的资源分配策略或锁的获取顺序导致的。 如果想要要避免死锁,就需要确保不同线程获取锁的顺序是一致的。

解决自己遇到的问题 分享认为有意义的知识 提供有一点点参考价值的灵感 6490

新手也能搞定!用ADS 2023从零设计一个超宽带Wilkinson功分器(附完整版图)

本文详细介绍了如何使用ADS 2023从零开始设计超宽带Wilkinson功分器,涵盖介质板参数设置、微带线计算优化、版图生成验证等关键步骤。通过实例演示和常见问题排查,帮助射频工程新手快速掌握功分器设计技巧,提升设计效率。

weixin_42692935的博客 477

麒麟V10等保三级配置实战:从auditd规则到PAM锁定的可信基线构建

Linux安全基线是信息系统可信运行的基础能力,其核心在于身份鉴别、访问控制与安全审计三大机制的协同落地。在国产化信创环境中,麒麟V10作为深度适配飞腾/鲲鹏平台的操作系统,其等保三级合规并非简单套用CentOS加固脚本,而是需围绕内核审计(auditd)、可插拔认证模块(PAM)及国产安全增强机制(如kysec)进行精细化编排。技术价值体现在将抽象条款(如GB/T 22239-2019中6.1.2、6.3.3条)转化为可验证的命令行操作,确保登录失败可锁定、关键行为可追溯、时间偏差不致日志失效。典型应用场

weixin_29969209的博客 599

Python学习:threading模块 lock、Rlock的使用

在使用多线程的应用下,如何保证线程安全,以及线程之间的同步,或者访问共享变量等问题是十分棘手的问题,也是使用多线程下面临的问题,如果处理不好,会带来较严重的后果,使用python多线程中提供Lock 、Rlock 、Semaphore 、Event 、Condition 用来保证线程之间的同步,后者保证访问共享变量的互斥问题。

Python热爱者的博客 1101

基于555定时器的D类功放设计:从PWM原理到无反馈电路实践

D类功放(数字功放)是一种高效率的音频放大技术,其核心原理是脉冲宽度调制(PWM)。它将输入的模拟音频信号转换为一系列高速开关的脉冲,通过控制功率开关管(如MOSFET)的通断,再经低通滤波器还原放大后的音频。相比传统AB类功放,其转换效率通常超过90%,显著降低了热能损耗。这项技术在追求高能效和小型化的现代音频设备中价值凸显,广泛应用于有源音箱、汽车音响和便携式设备。本文聚焦于一种独特的实现方案:以经典的555定时器芯片为核心,构建一个无整体负反馈的D类功放。通过剖析其PWM调制器、FET电压-电流转换级

weixin_30162121的博客 222

【python】详解threading模块:lock、Rlock的使用(二)

在之前的【python】多线程threading详解一文中,是有对多线程进行一个详细的梳理的。其中就提到了线程锁这一功能。主要基于Rlock实现。本文将进一步总结,丰富线程锁内容。 在使用多线程的应用下,如何保证线程安全,以及线程之间的同步,或者访问共享变量等问题是十分棘手的问题,也是使用多线程下面临的问题,如果处理不好,会带来较严重的后果,使用python多线程中提供Lock 、Rlock 、...

brucewong0516的博客 2万+

常见卫星图源下载教程

上面列出的8个常见的亚米级别数据源都可以通过xyz协议或者wmts/wms协议进行下载。这些协议是什么?地理信息数据为了方便网络传输,制定了一系列的地理数据传输标准(wms/wmts/xyz等)。协议特点优点缺点栅格数据支持矢量数据支持WMS通过HTTP请求获取GIS数据,服务器会将数据渲染成图像高度定制的地图;交互性强服务器渲染图像,响应时间较长支持有限支持WMTS提供预渲染的地图瓦片速度快,因为地图瓦片可以预先生成并在请求时快速提供瓦片的内容是预先确定的,无法进行定制支持。

锐多宝的地理空间 1万+

地磁场仿真与导航方案设计

地磁场仿真与导航方案设计 地磁场作为地球的固有资源,为航空、航天、航海提供了天然的坐标,可应用于航天器、航空飞行器和舰船等载体的定位、定向及姿态控制。本文依据地磁场的球谐模型,利用Matlab工具,设计了计算任意地点地磁场的程序,对仿真结果与实际数据进行对比分析;并选定一组卫星的数据,结合卫星的运动轨道,描绘90分钟内卫星处地磁总强度/矢量随轨道变化曲线,据此设计一种卫星地磁导航方案。 一、地磁场计算原理 1.1.球谐模型与球谐系数 地磁学的基本问题之一就是用数学表达式将地磁要素的地面分布表示成地理坐标的函

PRQKKK的博客 7410

python threading.lock_Python:使用threading模块实现多线程编程六[可重入锁RLock]

考虑这种情况:如果一个线程遇到锁嵌套的情况该怎么办,这个嵌套是指当我一个线程在获取临界资源时,又需要再次获取。根据这种情况,代码如下:Python代码 '''''Created on 2012-9-8@author: walfred@module: thread.ThreadTest6'''import threadingimport timecounter = 0mutex = threadi...

weixin_39535125的博客 133

OB4.X集群状态running但是oceanbase-ce is not running

自 V3.2.0 起,若 obd 设置了加密密钥,执行 display 命令输出的集群信息中,密码相关内容为加密状态。若需输出明文密码,可在命令中添加 --epk/–encryption-passkey 指定密钥用于验证。obd 运维的数据库,启停需要使用obd进行操作,停机时候没有使用obd会导致集群状态running但是oceanbase-ce is not running。查看集群中的租户时无租户反馈,警告oceanbase-ce is not running,但是查询集群状态明明是running。

qq961573863的博客 1216

Lock和Rlock

Lock.acquire([blocking]) 获取一把锁,阻塞的或者非阻塞的。 当调用时blocking参数设置为True(默认值),将阻塞直至锁变成unblocked,然后设置它的状态为locked并返回True。 当调用时blocking参数设置为False,将不会阻塞。 Lock.release() 释放一把锁。 当锁是locked时,重置它为unlocked,然后返回。如果存在其他阻塞...

weixin_43734271的博客 3979

3张RTX 4090就能跑!BAGEL-7B多模态模型本地部署避坑指南(附Flash Attention安装技巧)

本文详细介绍了如何在3张RTX 4090显卡上本地部署BAGEL-7B多模态模型,包括硬件配置、环境设置、多卡并行优化及常见问题解决方案。特别提供了Flash Attention安装技巧和显存优化策略,帮助开发者高效运行这一开源多模态模型,实现文本与图像生成任务。

1a2s3d4f5g的博客 653

【DaVinci Developer专题】-36-创建一个“既读又写”的Sender Receiver Port(SR PR-Port)

有时会遇到SWC需要对一个Port进行“既可以读,也可以写”的操作。以下图为例,Test_A_SWC中Test_A_Port是P-Port;Test_B_SWC中Test_A_Port是R-Port。Test_C_SWC需要对Test_A_Port同时进行“读”和“写”。 该篇将详细介绍PR-Port的创建方法。 目录 1 创建一个S/R Port Interface 2 将一个PR-Port端口添加至Application Component 3 PR-Port端口初始化 4 Run.

「汽车电子助手」的博客 3013

python的threading模块中threading.RLock和threading.Lock

在threading模块中,定义两种类型的锁:threading.Lock和threading.RLock。它们之间有一点细微的区别,通过比较下面两段代码来说明: import threading  lock = threading.Lock() #Lock对象  lock.acquire()  lock.acquire()  #产生了死锁。  lock.release()  lock.re

whaoXYSH的专栏 2713

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

python中threading模块详解及常用方法

 threading提供了一个比thread模块更高层的API来提供线程的并发性。这些线程并发运行并共享内存。          下面来看threading模块的具体用法:       一、Thread的使用 目标函数可以实例化一个Thread对象,每个Thread对象代表着一个线程,可以通过start()方法,开始运行。      这里对使用多线程并发,和不适用多线程并发

Goldxwang的博客 4万+

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

python Lock、RLock

Lock: 只能acquire一次,下一次acquire必须release后才能,不然会造成死锁 from threading import Lock total = 0 lock = Lock() def add(): #1. dosomething1 #2. io操作 # 1. dosomething3 global lock ...

weixin_30872789的博客 518

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

python3 threading.lock_(转)Python3入门之线程threading常用方法

原文:https://www.cnblogs.com/chengd/articles/7770898.htmlhttps://blog.youkuaiyun.com/sunhuaqiang1/article/details/70168015https://yq.aliyun.com/articles/26041?spm=5176.10695662.1996646101.searchclickresult.5d...

weixin_39533174的博客 371

Python之线程threading

1 threading模块 threading模块是在低级别_thread模块上构建的的高级别线程接口.继承_thread功能,易用性更强. _thread模块提供处理多进程(也称轻量级继承或任务)的基本单元,多进程控制特点是共享全局数据空间.简单锁(也称互斥或二进制信号量)可实现进程同步. 2 方法 from threading import * active_count() 或 import ...

天然玩家的博客 5601

python线程里嵌套锁问题lock和Rlock剖析

基础: 锁提供如下方法: 1.Lock.acquire(blocking=True, timeout=-1):请求对 Lock 或 RLock 加锁,其中 timeout 参数指定加锁多少秒。 Lock 和 RLock 的区别如下: threading.Lock:它是一个基本的锁对象,每次只能锁定一次,其余的锁请求,需等待锁释放后才能获取。 threading.RLock:它...

路奇的博客 1425

小猪的Python学习之旅 —— 7.Python并发之threading模块(1)

小猪的Python学习之旅 —— 7.Python并发之threading模块(1) 标签:Python 引言: 从本节开始的连续几节我们都会围绕着Python并发进行学习, 本节学习的

hong2511的博客 437

threading中的锁

threading.Lock   这个锁是不被某个特定线程所拥有的。一个线程获取了锁,之后任何线程尝试着获取锁,都会失败,包括这个获取了锁的线程自己尝试获取锁。   例如,如下代码就会堵塞 import threading lock = threading.Lock() lock.acquire() lock.acquire() lock.release() lock.release...

坑底Z蛙 1639

Python中threading模块

threading-更高级别的线程接口 源代码:Lib/threading.py 该模块在较低级别thread模块之上构建更高级别的线程接口。另请参见mutex和Queue模块。 该dummy_threading模块适用于threading因thread缺失而无法使用的情况 。 注意: 从Python 2.6开始,该模块提供 符合 PEP 8的别名和属性,以替换camelCase受J...

宇宙无敌大帅锅 3万+
上一篇: Python中os._exit(), sys.exit(), exit() 的区别
下一篇: webdriver 的三种等待方式(强制等待、隐式等待、显示等待)
Python热爱者
博客等级 码龄7年 3056粉丝 1330原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值