当前位置: 首页 > news >正文

聊聊并发与锁

持续坚持原创输出,点击蓝字关注我吧

1.并发与并行

并发可以充分地利用 CPU 资源,一般都会使用多线程实现。多线程的作用是提高任务的平均执行速度,但是会导致程序可理解性变差,编程难度加大。

关于对并发与并行的概念,大家可能一直比较混淆。

  1. 定义:并发指的是多个任务在同一时刻正在进行,但实际上只有一个任务在一段时间内被处理;并行指的是多个任务在同一时刻同时被处理。

  1. 时间:并发涉及的是任务的同时发生;并行涉及的是任务的同时处理。

  1. 实现:并发可以通过多线程实现,每个线程分别执行不同的任务;并行则需要多核处理器才能实现,多核处理器可以同时处理多个任务。

也可以通过举例说明二者的区别:

  1. 并发:一个人工作时候可以在写代码、听音乐和玩游戏三个任务中任意切换,但是你的大脑不能在同一时间处理任何两件事情。

  1. 并行:并行则是假如一个人有2个大脑,可以同时写代码、听音乐或玩游戏。

软件测试开发技术群

在并发环境下, 由于程序的封闭性被打破,出现了以下特点:

(1) 并发程序之间有相互制约的关系。直接制约体现为一个程序需要另一个程 序的计算结果,间接制约体现为多个程序竞争共享资源,如处理器、缓冲区等。

(2) 并发程序的执行过程是断断续续的。程序需要记忆现场指令及执行点。

(3) 当并发数设置合理并且 CPU 拥有足够的处理能力时,并发会提高程序的运行效率。

2.何为线程安全

线程安全是指程序的并发执行状态下,多个线程对共享数据进行操作时,不会因为线程交替执行和切换执行顺序,导致数据不一致、不合法或出现其他不确定状态。

为了实现线程安全,通常采用互斥机制,例如锁、信号量等,保证同一时刻只有一个线程访问共享数据,避免产生数据不一致的问题。

线程安全的核心理念就是“要么只读,要么加锁”。

3.如何理解锁

乐观锁假定其他事务不会对数据产生冲突,因此在修改数据之前不会对数据加锁。相反,它在修改数据时使用版本号或其他机制来检测冲突,如果发生冲突,则事务回滚。

悲观锁假定其他事务将对数据产生冲突,因此在访问数据时对数据加锁。悲观锁通常导致其他事务等待,直到锁被释放,因此它可能影响性能。

总的来说,乐观锁适用于并发性较高的环境,而悲观锁适用于并发性较低的环境,因为它更容易控制冲突。

下面是一个使用乐观锁的简单示例程序:

import time
​
class OptimisticLockExample:def __init__(self, initial_value=0, version=0):self.value = initial_valueself.version = version
​def update(self, new_value, current_version):if self.version != current_version:raise Exception("Version conflict")time.sleep(1) # Simulate a slow database update operationself.value = new_valueself.version += 1
​
if __name__ == "__main__":example = OptimisticLockExample()
​# Transaction 1current_version = example.versiontry:example.update(10, current_version)print("Transaction 1 successfully updated the value to 10")except Exception as e:print("Transaction 1 failed:", str(e))
​# Transaction 2current_version = example.versiontry:example.update(20, current_version)print("Transaction 2 successfully updated the value to 20")except Exception as e:print("Transaction 2 failed:", str(e))

上面的代码定义了一个类 OptimisticLockExample,该类具有两个属性:value 和 version。每次修改数据时,都会对当前的版本号进行检查,如果版本号不匹配,则会引发异常。

在代码的主程序中,创建了一个 OptimisticLockExample 对象,并尝试两次对该对象进行更新,打印出交易是否成功。

下面是一个使用悲观锁的简单示例程序:

import threading
import time
​
class PessimisticLockExample:def __init__(self, initial_value=0):self.value = initial_valueself.lock = threading.Lock()
​def update(self, new_value):with self.lock:time.sleep(1) # Simulate a slow database update operationself.value = new_value
​
if __name__ == "__main__":example = PessimisticLockExample()
​# Transaction 1try:example.update(10)print("Transaction 1 successfully updated the value to 10")except Exception as e:print("Transaction 1 failed:", str(e))
​# Transaction 2try:example.update(20)print("Transaction 2 successfully updated the value to 20")except Exception as e:print("Transaction 2 failed:", str(e))

上面的代码定义了一个类 PessimisticLockExample,该类具有一个属性 value 和一个互斥锁 lock。每次修改数据时,都会使用 with 语句对锁进行上锁,保证同一时刻只有一个线程在修改数据。

在代码的主程序中,我们创建了一个 PessimisticLockExample 对象,并尝试两次对该对象进行更新,打印出交易是否成功。

- END -


下方扫码关注 软件质量保障,与质量君一起学习成长、共同进步,做一个职场最贵Tester!

  • 后台回复【测开】获取测试开发xmind脑图

  • 后台回复【加群】获取加入测试社群方式,领2T测试自学视频

往期推荐

聊聊工作中的自我管理和向上管理

经验分享|测试工程师转型测试开发历程

聊聊UI自动化的PageObject设计模式

细读《阿里测试之道》

相关文章:

聊聊并发与锁

持续坚持原创输出,点击蓝字关注我吧1.并发与并行并发可以充分地利用 CPU 资源,一般都会使用多线程实现。多线程的作用是提高任务的平均执行速度,但是会导致程序可理解性变差,编程难度加大。关于对并发与并行的概念,大家…...

开源项目 —— 原生JS实现斗地主游戏 ——代码极少、功能都有、直接粘贴即用

目录 效果如下 目录结构 GameEntity.js GrawGame.js konva.min.js PlayGame.js veriable.js index.html 结语: 前期回顾 卡通形象人物2 写代码-睡觉 丝滑如德芙_0.活在风浪里的博客-CSDN博客本文实现了包含形象的卡通小人吃、睡、电脑工作的网页动画https://…...

Linux第四讲

目录 四、shell脚本 4.1 shell和shell脚本 4.2 脚本语言分类 4.2.1 编译型语言 4.2.2 解释型语言 4.2.3 脚本语言 4.3 shell常见种类 4.3.1 shell分类介绍 4.3.2 查看bash版本 4.3.3 sh和bash的关系 4.4 脚本书写规范 4.4.1 选择解释器 4.4.2 开发规范 4.5 shell…...

Redis 持久化

持久化是指数据写到物理硬盘里,即便程序崩溃、或者电脑重启,依然能够恢复。Redis提供了两种持久化机制:RDB和AOF。 RDB(Redis Database): RDB文件相当于内存快照,保存了某个时间点数据库信息。使用RDB文件恢复很简单,将…...

Python语言零基础入门教程(十三)

Python 字典(Dictionary) 字典是另一种可变容器模型,且可存储任意类型对象。 字典的每个键值 key:value 对用冒号 : 分割,每个键值对之间用逗号 , 分割,整个字典包括在花括号 {} 中 ,格式如下所示: d {key1 : value1, key2 : …...

江苏五年制专转本应该复习几轮?

五年制专转本应该复习几轮? 据调查统计:2022年专转本17%的考生复习三轮及以上,23%的考生复习了两轮。这两类的考生录取率高至85%。可见复习轮数多,专转本上岸的概率也大。综合多方因素,建议同学们专转本复习四轮&#…...

微信小程序的优化方案之主包与分包的研究

什么是分包? 某些情况下,开发者需要将小程序划分成不同的子包,在构建时打包成不同的分包,用户在使用时按需进行加载。 在构建小程序分包项目时,构建会输出一个或多个分包。每个使用分包小程序必定含有一个主包。所谓的…...

从手工测试转型web自动化测试继而转型成专门做自动化测试的学习路线。

在开始之前先自学两个工具 商业web自动化测试工具请自学QTP;QTP的学习可以跳过,我是跳过了的。 开源web自动化测试工具请自学Selenium;我当年是先学watir(耗时1周),再学selenium(也耗时1周&…...

【计组笔记03】计算机组成原理之系统五大部件介绍、主存模型和CPU结构介绍

这篇文章,主要介绍计算机组成原理之系统五大部件、主存模型和CPU结构。 目录 一、计算机五大部件 1.1、体系结构 (1)冯诺依曼体系结构...

微信小程序解析用户加密数据

微信公众号 IT果果日记前言在上一篇文章“微信小程序如何获取用户信息”中我们完成了用户明文数据的校验工作,本文将学习解密用户的非明文用户信息,也就是获取用户的openId和unionId。解密调用wx.getUserProfile后将返回encryptedData和iv两个数据。encr…...

毕业四年换了3份软件测试工作,我为何仍焦虑?

​今天一看日历:2023.2.11 ,才突然意识到自己毕业已经四年了。四年时间里一直在测试行业摸爬滚打,现在是时候记录一下了。 下面我来分享下我这4年软件测试经验及成长历程,或许能帮助你解决很多工作中的迷惑。 01、我是如何开始做…...

嵌入式C基础知识(7)

是否可以传递任何参数并从 ISR 返回值不可以。不能传递任何参数并从 ISR 返回值。 ISR 不返回任何内容,并且不允许传递任何参数。 当硬件或软件事件发生时调用 ISR,而代码不会调用它。 这就是为什么不向 ISR 传递参数的原因。 由于代码不调用 ISR&#x…...

大数据系列之:安装pulsar详细步骤

大数据系列之:安装pulsar详细步骤一、Pulsar版本和jdk对应关系二、安装JDK三、设置和激活jdk环境变量四、下载和解压Pulsar五、查看Pulsar目录六、启动Pulsar standalone cluster七、创建Kafka Topic八、往Topic写入数据九、消费pulsar的Topic一、Pulsar版本和jdk对…...

色彩-基础理论

颜色三大指标 色相 色相是颜色的一个属性,只有黑白灰没有色相这个属性(那银灰色是什么?) 颜色的相貌,指的也是给颜色一个名字 例如:暗红、酒红、土黄、墨绿 饱和度 颜色的鲜艳程度 纯度 饱和度主要取决于含色成分和消色成分&a…...

1629_MIT_6.828_xv6_chapter1操作系统的组织

全部学习汇总:GreyZhang/g_unix: some basic learning about unix operating system. (github.com) 这一次整理一下操作系统组织相关的知识,主要还是xv6教学操作系统相关的知识。当然,很多知识在这类技术领域是通用的。 1. 操作系统的主要功能…...

基于Golang哈希算法监控配置文件变化

SHA(secure hashing algorithm)表示安全哈希算法.SHA是MD5的修正版本,用于数据摘要和认证。哈希和加密类似,唯一区别是哈希是单项的,即哈希后的数据无法解密。SHA有不同的算法,主要包括SHA-1, SHA-2, SHA-256, SHA-512, SHA-224, …...

关于一笔画问题的一些思考(欧拉路Fleury算法、逐步插入回路法、以及另一种可能的解法)

前言这是一个经典的图论问题了最近复习离散的时候又恰好看到了,发现自己以前的解法似乎有点bug然后开始出反例卡自己,结果发现卡不掉?然后再好好想了想,发现这个看起来有问题的做法可能确实没问题。注意:欧拉路、欧拉回…...

vlookup怎么用详细步骤,看这一篇就够了

1、vlookup函数:使用方法 以下便是vlookup函数,功能、语法和参数用法: excel函数vlookup 2、vlookup函数:查询参数 首先,选中F2单元格,然后在编辑栏输入函数公式:VLOOKUP(E2,B&…...

雅思经验(9)之小作文常用词汇总结

写作:关于趋势的上升和下降在小作文中,真的是非常常见的,所以还是要积累一下。下面给出了很多词,但是在雅思写作中并不是词越丰富,分数就越高的。雅思写作强调的是准确性:在合适的地方用合适的词和句法。不…...

【Python语言基础】——Python NumPy 数组创建

Python语言基础——Python NumPy 数组创建 文章目录 Python语言基础——Python NumPy 数组创建一、Python NumPy 数组创建一、Python NumPy 数组创建 创建 NumPy ndarray 对象 NumPy 用于处理数组。 NumPy 中的数组对象称为 ndarray。 我们可以使用 array() 函数创建一个 NumP…...

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道(多模态 OCR → 语义检索 → 答案渲染)、两级检索(倒排 BM25 向量 HNSW)并以大语言模型兜底”的整体框架: 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后,分别用…...

内存分配函数malloc kmalloc vmalloc

内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...

阿里云ACP云计算备考笔记 (5)——弹性伸缩

目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...

学校招生小程序源码介绍

基于ThinkPHPFastAdminUniApp开发的学校招生小程序源码,专为学校招生场景量身打造,功能实用且操作便捷。 从技术架构来看,ThinkPHP提供稳定可靠的后台服务,FastAdmin加速开发流程,UniApp则保障小程序在多端有良好的兼…...

OPENCV形态学基础之二腐蚀

一.腐蚀的原理 (图1) 数学表达式:dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一,腐蚀跟膨胀属于反向操作,膨胀是把图像图像变大,而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...

以光量子为例,详解量子获取方式

光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学(silicon photonics)的光波导(optical waveguide)芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中,光既是波又是粒子。光子本…...

C++实现分布式网络通信框架RPC(2)——rpc发布端

有了上篇文章的项目的基本知识的了解,现在我们就开始构建项目。 目录 一、构建工程目录 二、本地服务发布成RPC服务 2.1理解RPC发布 2.2实现 三、Mprpc框架的基础类设计 3.1框架的初始化类 MprpcApplication 代码实现 3.2读取配置文件类 MprpcConfig 代码实现…...

阿里云Ubuntu 22.04 64位搭建Flask流程(亲测)

cd /home 进入home盘 安装虚拟环境: 1、安装virtualenv pip install virtualenv 2.创建新的虚拟环境: virtualenv myenv 3、激活虚拟环境(激活环境可以在当前环境下安装包) source myenv/bin/activate 此时,终端…...

实战设计模式之模板方法模式

概述 模板方法模式定义了一个操作中的算法骨架,并将某些步骤延迟到子类中实现。模板方法使得子类可以在不改变算法结构的前提下,重新定义算法中的某些步骤。简单来说,就是在一个方法中定义了要执行的步骤顺序或算法框架,但允许子类…...

【Kafka】Kafka从入门到实战:构建高吞吐量分布式消息系统

Kafka从入门到实战:构建高吞吐量分布式消息系统 一、Kafka概述 Apache Kafka是一个分布式流处理平台,最初由LinkedIn开发,后成为Apache顶级项目。它被设计用于高吞吐量、低延迟的消息处理,能够处理来自多个生产者的海量数据,并将这些数据实时传递给消费者。 Kafka核心特…...