聊聊并发与锁

news2024/11/18 4:29:37

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

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_value
        self.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 operation
        self.value = new_value
        self.version += 1
​
if __name__ == "__main__":
    example = OptimisticLockExample()
​
    # Transaction 1
    current_version = example.version
    try:
        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 2
    current_version = example.version
    try:
        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_value
        self.lock = threading.Lock()
​
    def update(self, new_value):
        with self.lock:
            time.sleep(1) # Simulate a slow database update operation
            self.value = new_value
​
if __name__ == "__main__":
    example = PessimisticLockExample()
​
    # Transaction 1
    try:
        example.update(10)
        print("Transaction 1 successfully updated the value to 10")
    except Exception as e:
        print("Transaction 1 failed:", str(e))
​
    # Transaction 2
    try:
        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设计模式

细读《阿里测试之道》

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/338727.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

共享模型之无锁(三)

1.原子累加器 示例代码: public class TestAtomicAdder {public static void main(String[] args) {for (int i 0; i < 5; i) {demo(() -> new AtomicLong(0),(adder) -> adder.getAndIncrement());}for (int i 0; i < 5; i) {demo(() -> new LongAdder(),(…

C++复习笔记6

1.String类的实现 注意深浅拷贝&#xff0c; C语言字符串拼接函数strcat() #define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<vld.h> #include<assert.h> using namespace std;class String {friend ostream& operator<<(ostream &am…

【DSView逻辑分析抓取波形CAN步骤-硬件连接-数据解析-底层波形认识CAN-工具使用】

【DSView逻辑分析抓取波形CAN步骤-硬件连接-数据解析-底层波形认识CAN】1、概述2、实验环境3、写在前面的一个问题4、实验准备&#xff08;1&#xff09;硬件连接1&#xff09;CAN卡连接开发板&#xff08;2&#xff09;逻辑分析仪连接开发板&#xff08;2) CAN卡连接软件&…

Linux 文件锁 - fcntl

什么是文件锁&#xff1f; 即锁住文件&#xff0c;不让其他程序对文件做修改&#xff01; 为什么要锁住文件&#xff1f; 案例&#xff0c;有两个程序&#xff0c;都对一个文件做写入操作。 #include <unistd.h> #include <stdio.h> #include <stdlib.h> …

【集群】Slurm作业调度系统的使用

最近使用集群进行实验&#xff0c;记录并学习集群系统进行深度学习的实验过程。集群所使用的作业调度系统为Slurm&#xff0c;这里记录下使用的常用命令和一些注意事项。 Slurm简介 Slurm是一个开源&#xff0c;容错&#xff0c;高度可扩展的集群管理和作业调度系统&#xff0…

excel数据处理: 如何用99个空格提取单元格数据

脑洞大开&#xff0c;提取单元格数据用99个空格就成&#xff01;真想扒开那些大神的脑袋看看&#xff0c;是怎么想出这样匪夷所思的方法的。需要从规格型号中提取容值、封装、耐压三组数据&#xff0c;如下&#xff1a;数据源在A列&#xff0c;数据量很大&#xff0c;需要提取的…

微信小程序Springboot短视频分享系统

3.1小程序端 用户注册页面&#xff0c;输入用户的个人信息点击注册即可。 注册完成后会返回到登录页面&#xff0c;用户输入自己注册的账号密码即可登录成功 登录成功后我们可以看到有相关的视频还有视频信息&#xff0c;我的信息等。 视频信息推荐是按照点击次数进行推荐的&am…

Zabbix 构建监控告警平台(四)

Zabbix ActionZabbix Macros1.Zabbix Action 1.1动作Action简介 当某个触发器状态发生改变(如Problem、OK)&#xff0c;可以采取相应的动作&#xff0c;如&#xff1a; 执行远程命令 邮件&#xff0c;短信&#xff0c;微信告警,电话 1.2告警实验简介 1. 创建告警media type&…

9.语义HTMLVScode扩展推荐

语义HTML 定义&#xff1a; 一个元素使用我们并不是只关心他是什么样子的&#xff0c;而是要去关心这个元素名称的实际意义或者代表什么 我们使用标签并不是他仅代表导航栏&#xff0c;只是将导航栏部分归为一个块。现实生活中&#xff0c;多使用之前都是使用div这个元素去构…

删除有序数组中的重复项-力扣26-java

一、题目描述给你一个 升序排列 的数组 nums &#xff0c;请你 原地 删除重复出现的元素&#xff0c;使每个元素 只出现一次 &#xff0c;返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。由于在某些语言中不能改变数组的长度&#xff0c;所以必须将结果放在数组nums…

软件设计(九)

软件设计&#xff08;八&#xff09;https://blog.csdn.net/ke1ying/article/details/128954569?spm1001.2014.3001.5501 81、模块A将学生信息&#xff0c;即学生姓名、学号、手机等放到一个结构体系中&#xff0c;传递给模块B&#xff0c;模块A和B之间的耦合类型为 什么耦合…

【C++设计模式】学习笔记(1):面向对象设计原则

目录 简介面向对象设计原则(1)依赖倒置原则(DIP)(2)开放封闭原则(OCP)(3)单一职责原则(SRP)(4)Liskov替换原则(LSP)(5)接口隔离原则(ISP)(6)优先使用对象组合,而不是类继承(7)封装变化点(8)针对接口编程,而不是针对实现编程结语简介 Hello! 非常感谢您阅读海…

变分自编码器背后的直觉【VAE】

在阅读有关机器学习的内容时&#xff0c;你遇到的大部分材料可能都与分类问题有关。 你有一个特定的输入&#xff0c;ML 模型试图找出该输入的特征。 例如&#xff0c;分类模型可以决定图像中是否包含猫。 当你想创建具有预定义特征的数据时&#xff0c;反过来又如何呢&#x…

再不跳槽,就晚了

从时间节点上来看&#xff0c;3月、4月是每年跳槽的黄金季&#xff01; 以 BAT 为代表的互联网大厂&#xff0c;无论是薪资待遇、还是平台和福利&#xff0c;都一直是求职者眼中的香饽饽&#xff0c;“大厂经历” 在国内就业环境中无异于一块金子招牌。在这金三银四的时间里&a…

预处理指令详解

预处理指令详解**1.预定义符号****2.#define****2.1 #define 定义标识符****2.2 #define 定义宏****2.3 #define 替换规则****2.4 #和##****#的作用****##的作用****2.5 带副作用的宏参数****2.6 宏和函数的对比****宏和函数对比图****2.7 命名约定****3.#undef**4.条件编译4.1…

Leg转Goh引擎和架设单机+配置登陆器教程

教程准备1、Leg版本一个2、Goh引擎一套3、电脑一台(最好联网)前言&#xff1a;BLUE/LEGS/Gob/Goh/九龍、4K、AspM2第一步&#xff1a;更换引擎1、把版本自带的LEG引擎换成Goh引擎2、删除服务端里面的exe、dll文件(也可以直接更新)3、清理登录和游戏网关里面的配置文件4、更新引…

Sandman:一款基于NTP协议的红队后门研究工具

关于Sandman Sandman是一款基于NTP的强大后门工具&#xff0c;该工具可以帮助广大研究人员在一个安全增强型网络系统中执行红队任务。 Sandman可以充当Stager使用&#xff0c;该工具利用了NTP&#xff08;一个用于计算机时间/日期同步协议&#xff09;从预定义的服务器获取并…

菌子导航系统(持续开发中)

文章目录菌子导航前言项目架构spring-cloud 和 spring-boot 版本选择使用到的组件&#xff08;依赖&#xff09;架构分层项目基本功能1 使用Nacos做配置中心2 logback日志3 mybatis-plus操作数据库4 Caffeine 缓存整合5 LocalDateTime 序列化&反序列化6 参数校验快速失败配…

ubuntu20.04 系统下 .7z 文件解压缩到指定的目录下

问题描述 环境&#xff1a; ubuntu 20.04 ubuntu 下有个 7z 的压缩文件需要解压&#xff0c;需要解压到指定的目录下&#xff0c;而不是压缩包当前目录下 安装 p7zip-full ubuntu 下的 7z 解压软件&#xff1a; p7zip-full 安装命令&#xff1a; sudo apt install p7zip-fu…

04-PS人像磨皮方法

1.高斯模糊磨皮 这种方法的原理就是建立一个将原图高斯模糊后图层, 然后用蒙版加画笔或者历史画笔工具将需要磨皮的地方涂抹出来, 通过图层透明度, 画笔流量等参数来控制磨皮程度 1.新建图层(命名为了高斯模糊磨皮), 混合模式设置为正常, 然后选择高斯模糊, 模糊数值设置到看…