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

Golang开发--互斥锁和读写锁

互斥锁(Mutex)

互斥锁(Mutex)是一种并发控制机制,用于保护共享资源的访问。互斥锁用于确保在任何给定时间只有一个 goroutine(Go 语言中的并发执行单元)可以访问被保护的共享资源,从而避免竞争条件和数据竞争。

Go 语言提供了 sync 包来支持互斥锁的实现,其中最常用的互斥锁类型是 sync.Mutex。下面是互斥锁的基本使用示例:

import ("sync"
)var (counter intmutex   sync.Mutex
)func increment() {mutex.Lock()         // 获取互斥锁defer mutex.Unlock() // 在函数退出时释放互斥锁counter++
}func main() {// 启动多个 goroutine 并发执行 increment 函数for i := 0; i < 10; i++ {go increment()}// 等待所有 goroutine 执行完毕time.Sleep(time.Second)fmt.Println(counter) // 输出: 10
}

在上述示例中,我们使用了 sync.Mutex 类型的互斥锁来保护 counter 变量的访问。increment 函数中的 mutex.Lock() 调用会获取互斥锁,确保只有一个 goroutine 可以进入临界区(即修改 counter 变量的部分)。使用 defer mutex.Unlock() 语句,无论函数如何返回,都会在函数退出时释放互斥锁,确保解锁操作得以执行。

在主函数中,我们启动了多个 goroutine 并发执行 increment 函数,每个 goroutine 都会对 counter 变量进行递增操作。通过互斥锁的保护,确保每次递增操作的原子性,避免了数据竞争。

需要注意以下几点:

  • 在使用互斥锁时,需要确保在访问共享资源之前获取锁,在使用完毕之后释放锁。可以使用 mutex.Lock() 获取锁,使用 mutex.Unlock() 释放锁。为了确保锁的释放操作一定会执行,可以使用 defer 语句将 mutex.Unlock() 延迟到函数退出时执行。

  • 在使用互斥锁时,应尽量减小临界区的范围,以允许更多的并发执行。只有在需要保护共享资源的具体操作时才获取锁,在操作完成后尽快释放锁。

  • 互斥锁是一种独占锁,意味着只有一个 goroutine 可以获取到锁并执行临界区代码,其他 goroutine 需要等待锁的释放。这可能会导致性能瓶颈,因此在设计并发程序时需要权衡锁的使用和程序的性能需求。

读写锁(Read-Write Lock)

读写锁(Read-Write Lock)是一种并发控制机制,用于在多个读操作和写操作之间提供互斥访问。读写锁允许多个读操作同时进行,但只允许一个写操作进行,以保证数据的一致性和完整性。Go 语言提供了 sync 包来实现读写锁。

sync 包中的 RWMutex 类型是用于实现读写锁的结构体。下面是关于读写锁的详细解释:

创建读写锁:
可以通过创建 sync.RWMutex 类型的变量来创建读写锁:

var rwMutex sync.RWMutex

读操作:
使用读锁(RLock)可以允许多个并发读操作,但阻止写操作。读锁的使用方式如下:

rwMutex.RLock() // 获取读锁
// 执行读操作
rwMutex.RUnlock() // 释放读锁

写操作:
使用写锁(Lock)可以阻止其他的读操作和写操作。写锁的使用方式如下:

rwMutex.Lock() // 获取写锁
// 执行写操作
rwMutex.Unlock() // 释放写锁

读写锁的特性:

多个读操作可以同时进行,互不干扰。
读操作和写操作之间是互斥的,即写操作需要等待所有读操作完成。
写操作需要独占锁,不允许其他读操作和写操作同时进行。
读写锁的设计是基于对数据访问的优化,以提高并发性能。当对共享数据进行频繁的读操作时,可以使用读写锁来允许多个并发的读操作,而不会阻塞彼此。只有在需要修改共享数据时,才需要获取写锁,此时会阻塞其他的读操作和写操作。

需要注意的是,读写锁应该被谨慎使用,只有在确实需要对共享数据进行读写控制时才使用。滥用读写锁可能会导致性能问题和竞态条件。

下面是一个简单的示例,演示如何使用读写锁:

package mainimport ("fmt""sync""time"
)var (data      map[string]stringrwMutex   sync.RWMutexwaitGroup sync.WaitGroup
)func main() {data = make(map[string]string)waitGroup.Add(2)go writeData("key", "value")go readData("key")waitGroup.Wait()
}func writeData(key, value string) {rwMutex.Lock()data[key] = valuefmt.Println("Write:", key, value)rwMutex.Unlock()waitGroup.Done()
}func readData(key string) {rwMutex.RLock()value := data[key]fmt.Println("Read:", key, value)rwMutex.RUnlock()waitGroup.Done()
}

在上面的示例中,我们创建了一个 data map 作为共享数据,使用 sync.RWMutex 来保护这个共享数据的读写。writeData 函数获取写锁,向 data map 中写入数据。readData 函数获取读锁,从 data map 中读取数据。通过使用读写锁,写操作和读操作可以并发进行。

读写锁提供了一种有效的并发控制机制,使得多个读操作和写操作可以在一定程度上同时进行,以提高程序的性能。但是,需要根据实际情况仔细评估并使用读写锁,以避免过度同步或竞态条件的问题。

相关文章:

Golang开发--互斥锁和读写锁

互斥锁&#xff08;Mutex&#xff09; 互斥锁&#xff08;Mutex&#xff09;是一种并发控制机制&#xff0c;用于保护共享资源的访问。互斥锁用于确保在任何给定时间只有一个 goroutine&#xff08;Go 语言中的并发执行单元&#xff09;可以访问被保护的共享资源&#xff0c;从…...

Springboot 集成WebSocket作为客户端,含重连接功能,开箱即用

使用演示 public static void main(String[] args) throws Exception{//初始化socket客户端BaseWebSocketClient socketClient BaseWebSocketClient.init("传入链接");//发送消息socketClient.sendMessage("填写需要发送的消息", (receive) -> {//这里…...

java调整字符串

package 字符串练习;public class 调整字符串 {/* 如果调整成功则给提示,返回不成功也给提示调整 例如:abcde -> bcdea -> cdeab 就是把第一个值放到最后的位置上现在是给定两个字符串, 选定其中一个进行调整, (我们想一下,如果调整字符串的长度次,那不就是返回到原来的字…...

2023-9

内核向应用层发送netlink单播消息&#xff1a; nlmsg_unicast -> netlink_unicast -> netlink_sendskb -> __netlink_sendskb -> 把skb链入struct sock 的 sk_receive_queue 链表中&#xff0c;再调用sk->sk_data_ready(sk); -> sock_def_readable -> wak…...

软考高级+系统架构设计师教程+第二版新版+电子版pdf

注意&#xff01;&#xff01;&#xff01; 系统架构设计师出新版教程啦&#xff0c;2022年11月出版。所以今年下半年是新版第一次考试&#xff0c;不要再复习老版教程了&#xff0c;内容改动挺大的。 【内容简介】系统架构设计师教程&#xff08;第2版&#xff09;作为全国计…...

【产品运营】如何提升B端产品竞争力(下)

“好产品不是能力内核&#xff0c;做好产品的流程才是” 一、建立需求池和需求反馈渠道 需求池管理是B端产品进化最重要的环节&#xff0c;它的重要性远超产品设计、开发等其他环节。 维护需求池有主动和被动两种。 主动维护是产品经理在参与售前、迭代、交付、售后、竞品分…...

uniapp 微信小程序使用echarts

本文目的&#xff1a;通过分包的方式&#xff0c;尽可能在微信小程序中使用最新的echarts。 当然你也可以直接使用现成的uchart或者市场里别人封好的echarts. 准备工作 下载echarts-for-weixin源码。 复制ec-canvas文件夹以及下属文件&#xff0c;在uniapp项目中与pages同级的地…...

【漏洞复现】企望制造 ERP命令执行

漏洞描述 由于企望制造 ERP comboxstore.action接口权限设置不当&#xff0c;默认的配置可执行任意SQL语句&#xff0c;利用xp_cmdshell函数可远程执行命令&#xff0c;未经认证的攻击者可通过该漏洞获取服务器权限。 免责声明 技术文章仅供参考&#xff0c;任何个人和组织…...

2023 “华为杯” 中国研究生数学建模竞赛(E题)深度剖析|数学建模完整代码+建模过程全解全析

​ 问题一 血肿扩张风险相关因素探索建模 思路&#xff1a; 根据题目要求,首先需要判断每个患者是否发生了血肿扩张事件。根据定义,如果后续检查的血肿体积比首次检查增加≥6 mL或≥33%,则判断为发生了血肿扩张。 具体判断步骤: (1) 从表1中提取每个患者的入院首次影像检查…...

【腾讯云国际站】CDN内容分发网络特性介绍

为什么使用腾讯云国际站 CDN 内容分发网络&#xff1f; 当用户直接访问源站中的静态内容时&#xff0c;可能面临的体验问题&#xff1a; 客户离服务器越远&#xff0c;访问速度越慢。客户数量越多&#xff0c;网络带宽费用越高。跨境用户访问体验较差。 腾讯云国际站CDN 如何改…...

【工业机器人视觉】

工业机器人视觉 工业机器人的定位、抓取任务是工业生产线上一项重要的应用&#xff0c;一般通过预先示教的方式让机器人执行预定的指令动作。但是&#xff0c;一旦工件的状态发生改变时&#xff0c;机器人便无法完成工作任务。区别&#xff1a;就像人睁眼走直线和闭眼走直线。…...

跨域(浏览器)

跨域问题 是前端开发中常遇到的一个挑战。由于浏览器的同源策略限制&#xff0c;前端在发起异步请求时会受到限制&#xff0c;只能向相同源&#xff08;域名、协议和端口号都相同&#xff09;的服务器发送请求。当请求的目标服务器与当前页面的源不一致时&#xff0c;就会触发…...

Leetcode 2866. Beautiful Towers II

Leetcode 2866. Beautiful Towers II 1. 解题思路2. 代码实现 题目链接&#xff1a;2866. Beautiful Towers II 1. 解题思路 这一题其实思路上还是比较明显的&#xff0c;就是一个单调数组的问题&#xff0c;问题在于说如果具体去设计这个单调数组。 我们从题目出发&#x…...

电脑C盘爆红怎么办?(小白篇)

文章目录 前言&#xff1a;1、清理临时和系统文件2、更改电脑默认软件安装位置3、微信、QQ文件存储路径放在其它盘4、卸载一些不常用的软件彩蛋 前言&#xff1a; C盘作为电脑的系统盘&#xff0c;如果出现爆满或者剩余空间很小整个C盘变红&#xff0c;这样会导致电脑系统运行…...

Office Xml 2003转XLSX

一、使用到的依赖包 1、xelem-3.1.jar 下载地址&#xff1a;管网下载地址 2、poi-3.17.jar 下载地址&#xff1a;https://mvnrepository.com/artifact/org.apache.poi/poi 二、实现方法 1、Xml2003公式转XLSX公式算法 &#xff08;1&#xff09;Xml2003函数格式 SUM(R[-1…...

skyWalking搭建(一)

title: “SkyWalking搭建(一)” createTime: 2021-07-27T14:34:2108:00 updateTime: 2021-07-27T14:34:2108:00 draft: false author: “name” tags: [“skywalking”] categories: [“java”] description: “测试的” 基于 docker 部署 skywalking 并实现 SpringBoot 全链路…...

Golang开发--sync.WaitGroup

sync.WaitGroup 是 Go 语言标准库中的一个并发原语&#xff0c;用于等待一组并发操作的完成。它提供了一种简单的方式来跟踪一组 goroutine 的执行状态&#xff0c;并在所有 goroutine 完成后恢复执行。 下面是关于 sync.WaitGroup 的实现细节的详细解释&#xff1a; 创建 Wa…...

Linux命令教程:使用cat命令查看和处理文件

文章目录 教程&#xff1a;使用cat命令在Linux中查看和处理文件1. 引言2. cat命令的基本概述3. 查看文件内容4. 创建文件5. 文件重定向和管道6. 格式化和编辑文件7. 实际应用示例7.1 使用cat命令浏览日志文件7.2 利用cat命令合并多个配置文件7.3 使用cat命令将文件内容发送到其…...

Websocket集群解决方案以及实战(附图文源码)

最近在项目中在做一个消息推送的功能&#xff0c;比如客户下单之后通知给给对应的客户发送系统通知&#xff0c;这种消息推送需要使用到全双工的websocket推送消息。 所谓的全双工表示客户端和服务端都能向对方发送消息。不使用同样是全双工的http是因为http只能由客户端主动发…...

科技的成就(五十一)

397、初等数论的不可解问题 1936 年 4 月&#xff0c;邱奇证明判定性问题不可解。33 岁的邱奇发表论文《初等数论的不可解问题》&#xff0c;运用λ演算给出了判定性问题一个否定的答案。λ演算是一套从数学逻辑中发展起来的形式系统&#xff0c;采用变量绑定和替换&#xff0c…...

TDengine 快速体验(Docker 镜像方式)

简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能&#xff0c;本节首先介绍如何通过 Docker 快速体验 TDengine&#xff0c;然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker&#xff0c;请使用 安装包的方式快…...

srs linux

下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935&#xff0c;SRS管理页面端口是8080&#xff0c;可…...

【算法训练营Day07】字符串part1

文章目录 反转字符串反转字符串II替换数字 反转字符串 题目链接&#xff1a;344. 反转字符串 双指针法&#xff0c;两个指针的元素直接调转即可 class Solution {public void reverseString(char[] s) {int head 0;int end s.length - 1;while(head < end) {char temp …...

视频字幕质量评估的大规模细粒度基准

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用&#xff0c;因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型&#xff08;VLMs&#xff09;在字幕生成方面…...

数据库分批入库

今天在工作中&#xff0c;遇到一个问题&#xff0c;就是分批查询的时候&#xff0c;由于批次过大导致出现了一些问题&#xff0c;一下是问题描述和解决方案&#xff1a; 示例&#xff1a; // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...

OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别

OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...

Web 架构之 CDN 加速原理与落地实践

文章目录 一、思维导图二、正文内容&#xff08;一&#xff09;CDN 基础概念1. 定义2. 组成部分 &#xff08;二&#xff09;CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 &#xff08;三&#xff09;CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 &#xf…...

FFmpeg:Windows系统小白安装及其使用

一、安装 1.访问官网 Download FFmpeg 2.点击版本目录 3.选择版本点击安装 注意这里选择的是【release buids】&#xff0c;注意左上角标题 例如我安装在目录 F:\FFmpeg 4.解压 5.添加环境变量 把你解压后的bin目录&#xff08;即exe所在文件夹&#xff09;加入系统变量…...

解决:Android studio 编译后报错\app\src\main\cpp\CMakeLists.txt‘ to exist

现象&#xff1a; android studio报错&#xff1a; [CXX1409] D:\GitLab\xxxxx\app.cxx\Debug\3f3w4y1i\arm64-v8a\android_gradle_build.json : expected buildFiles file ‘D:\GitLab\xxxxx\app\src\main\cpp\CMakeLists.txt’ to exist 解决&#xff1a; 不要动CMakeLists.…...

springboot 日志类切面,接口成功记录日志,失败不记录

springboot 日志类切面&#xff0c;接口成功记录日志&#xff0c;失败不记录 自定义一个注解方法 import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;/***…...