当前位置: 首页 > 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…...

PHP和Node.js哪个更爽?

先说结论&#xff0c;rust完胜。 php&#xff1a;laravel&#xff0c;swoole&#xff0c;webman&#xff0c;最开始在苏宁的时候写了几年php&#xff0c;当时觉得php真的是世界上最好的语言&#xff0c;因为当初活在舒适圈里&#xff0c;不愿意跳出来&#xff0c;就好比当初活在…...

为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?

在建筑行业&#xff0c;项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升&#xff0c;传统的管理模式已经难以满足现代工程的需求。过去&#xff0c;许多企业依赖手工记录、口头沟通和分散的信息管理&#xff0c;导致效率低下、成本失控、风险频发。例如&#…...

系统设计 --- MongoDB亿级数据查询优化策略

系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log&#xff0c;共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题&#xff0c;不能使用ELK只能使用…...

【项目实战】通过多模态+LangGraph实现PPT生成助手

PPT自动生成系统 基于LangGraph的PPT自动生成系统&#xff0c;可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析&#xff1a;自动解析Markdown文档结构PPT模板分析&#xff1a;分析PPT模板的布局和风格智能布局决策&#xff1a;匹配内容与合适的PPT布局自动…...

ip子接口配置及删除

配置永久生效的子接口&#xff0c;2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...

Visual Studio Code 扩展

Visual Studio Code 扩展 change-case 大小写转换EmmyLua for VSCode 调试插件Bookmarks 书签 change-case 大小写转换 https://marketplace.visualstudio.com/items?itemNamewmaurer.change-case 选中单词后&#xff0c;命令 changeCase.commands 可预览转换效果 EmmyLua…...

Unity VR/MR开发-VR开发与传统3D开发的差异

视频讲解链接&#xff1a;【XR马斯维】VR/MR开发与传统3D开发的差异【UnityVR/MR开发教程--入门】_哔哩哔哩_bilibili...

Monorepo架构: Nx Cloud 扩展能力与缓存加速

借助 Nx Cloud 实现项目协同与加速构建 1 &#xff09; 缓存工作原理分析 在了解了本地缓存和远程缓存之后&#xff0c;我们来探究缓存是如何工作的。以计算文件的哈希串为例&#xff0c;若后续运行任务时文件哈希串未变&#xff0c;系统会直接使用对应的输出和制品文件。 2 …...

倒装芯片凸点成型工艺

UBM&#xff08;Under Bump Metallization&#xff09;与Bump&#xff08;焊球&#xff09;形成工艺流程。我们可以将整张流程图分为三大阶段来理解&#xff1a; &#x1f527; 一、UBM&#xff08;Under Bump Metallization&#xff09;工艺流程&#xff08;黄色区域&#xff…...

简单介绍C++中 string与wstring

在C中&#xff0c;string和wstring是两种用于处理不同字符编码的字符串类型&#xff0c;分别基于char和wchar_t字符类型。以下是它们的详细说明和对比&#xff1a; 1. 基础定义 string 类型&#xff1a;std::string 字符类型&#xff1a;char&#xff08;通常为8位&#xff09…...