简单探讨一下python线程锁
作者:真的不能告诉你我的名字 发布时间:2021-03-24 12:06:54
为什么需要线程锁
当我们访问一些特殊的数据时,需要保证该数据的原子性,比如: 文章的阅读量、文章的点赞量等。我们必须要确保这些共享数据必须是原子性的,否则的话,多线程同时访问的时候,可能会出现异常情况,什么是原子性呢?原子性是指一个操作是不可能被中途中断的,要不全部完成,要不没有完成,这么说,可能不理解,下面举个例子来说明一下原子性的重要性:
比如我们写一个程序,来模拟10个人点赞,最后输出阅读量的值,代码如下:
代码初看好像没什么问题,反正核心点就是阅读量+1,当运行就,就出现问题了,
上述代码,运行了5次,出现了5次不一样的结果。这就是出现了竞争,所以我们需要加一个锁,来确保该阅读量函数的原子性。
线程锁使用
python
中的threading
模块,提供的锁就只有一种,我们使用Lock
定义锁,例如:
Lock = threading.Lock()
如果需要对资源进行上锁的话,使用acquire
方法即可,例如:
Lock.acquire()
如果需要对资源进行解锁的话,使用release
方法即可,例如:
Lock.release()
除此之外,threading
模块还提供了RLock
可重入锁,可重入锁的作用和普通锁一样,用于保护资源,以保证并发访问不会出现问题,但是与普通锁不同的是,可重入锁允许同一个线程在持有锁的情况下多次获取该锁而不会发生死锁。但是在持有多少次锁,也必须释放多少次锁,否则会出现问题。
案例说明线程锁
上述我们介绍了线程锁,这里将addReaderCount
进行加锁和解锁的操作,代码如下:
上述代码在源代码的基础上,在最开始使用Lock
定义了一个锁,而后再函数开始之前进行一个加锁acquire()
,这样的话,其他函数在执行的时候,发现这个是已经锁住了的,所以会等待,等待解锁后(releas()
)再进行该函数,而函数又会加锁,如此往复,能够确保在同一时刻,addReaderCount
函数只执行一次。
执行程序结果为:
可以发现,这次的结果阅读量的值终于符合我们的预期了。
实现一个读写锁
在python
中,原生是没有读写锁的,只能借助第三方来实现,这里我们可以实现一个简单的读写锁。
在写之前,我们需要先了解下读写锁的作用到底是什么?读写锁将资源拆分为读和写2种操作,读锁允许多个线程同时读取共享资源,提高并发性能。但是当需要修改共享资源的时候,只能允许一个线程修改该共享资源,并且在修改完毕前,不允许读请求,以便造成数据不一致。所以操作完毕后,开放读请求。
这里为了实验,写了一个最简单的读写锁,安全性和效率都得不到保证,若想使用读写锁,可以使用第三方的读写锁。
我们自己写的读写锁代码如下:
上述代码,我们实现了一个读写锁类RWLock
,其中有4个方法,分别为:
writeLock
:写锁writeUnlock
:释放写锁readLock
:读锁readUnlock
: 释放读锁
由于读锁可以同一时刻被调用,所以我们使用的变量readCount
来定义的,等需要读锁的是,readCount
会+1,可以一直调用下去,而如果需要写锁的时候,这里是先将写锁变量Locked
定义为True
,若此时再次调用读写,会让其等待,而在写锁中,会等待读锁读取完毕后(readCount
为0的时候),再进行写锁的请求。写锁执行完毕后,会将Locked
给重置为False
。
这里写一个小的调用方法来调用一下:
上述代码,在reads
和writes
方法中,分表调用我们之前定义的读锁和写锁,代码中定义了9个线程,分别是调用了6次读,以及3次写。
效果我们来看下:
从上述结果中,我们不难发现,在没有写锁情况下,我们使用读锁,可以访问同一资源,当使用写锁后,读锁会暂停,当写锁执行完毕后,读锁才会继续批量执行。
来源:https://juejin.cn/post/7224874901815492668


猜你喜欢
- 最近在一个python工具中需要实现串口自动触发工作的功能,之前只在winform上面实现,今天使用python试试。这里简单记一下:首先用
- property() 函数的作用是在新式类中返回属性值。Python中有一个property的语法,它类似于C#的get set语法,其功能
- 前言最近在写 echarts 的时候碰到了这么一个报错,如下图。造成报错的原因是因为 echarts 的图形容器还未生成就对其进行了初始化,
- 在python中可以使用json将数据格式化为JSON格式:1.将字典转换成JSON数据格式:s=['张三','年龄
- 一,集群搭建步骤1.先在一台虚拟机配置jdk,hadoop2.克隆3.修改网络等相关配置当我们使用虚拟机时,可能自然而然的会想上面的步骤一样
- 前言:本文的主要内容是介绍Python中字典及其使用,包括使用字典(添加、删除、修改等操作)、遍历字典以及字典与列表之间的嵌套使用,文中附有
- 1、df=DataFrame([{‘A':'11','B':'12'},{‘A
- 使用python去除文中的某个字符是非常麻烦的一件事,不同的环境可以用到多种方法,例如正则表达式,del语法,现在发布的是一个比较简单易行的
- MAC地址也叫物理地址、硬件地址,由网络设备制造商生产时烧录在网卡(Network lnterface Card)的EPROM(一种闪存芯片
- 很多时候我们写的程序,会花上一分钟甚至几分钟时间。为了使软件使用者能够耐心的等待程序的执行,我们经常会希望有一个进度条来表示程序执行的状态。
- sql不常用函数总结以及事务,增加,删除触发器 distinct 删除重复行 declare @x 申明一个变量 convert(varch
- 有时候我们需要程序截图文章中的部分字符作为摘要显示出来,这时我们一般是只希望提取的字符串是纯文本的,没有如何html标签,如果我们章节用le
- 数据库和操作系统一样,是一个多用户使用的共享资源。当多个用户并发地存取数据 时,在数据库中就会产生多个事务同时存取同一数据的情况。若对并发操
- 语法格式如下:assert expression等价于:if not expression: raise AssertionErrorass
- (1)、back_log:要求 MySQL 能有的连接数量。当主要MySQL线程在一个很短时间内得到非常多的连接请求,这就起作用,然后主线程
- 如果你想让你的IIS支持wml,做个wap网站,只需作小小的改变就行了.虽然目前支持wml的虚拟主机极少,但是自己在本机上玩玩也好的.首先在
- console 打印乱码1.File Encoding设置项目编码为GBK2.文件模板设定python脚本为# -*- coding: ut
- 改代码是在windows 系统下打开路径和保存路径换成自己的就可以啦~import numpy as npimport matplotlib
- 1. 监测端口我们要引用的socket模块来校验端口是否被占用。1.1 socket是什么?简单一句话:网络上的两个程序通过一个双向的通信连
- 一直想了解Web编程的技术。PHP是进行Web编程重要的一种语言,书上总是说,PHP是用于服务器端的编程语言。但是,实在不能理解它是怎么用于