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 中读取数据。通过使用读写锁,写操作和读操作可以并发进行。

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

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

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

相关文章

计算机毕业设计 基于HTML语言的环保网站的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

SVN状态图标不显示

问题可能点1&#xff1a;图标覆盖 1、右键找到设置 2、找到图标覆盖 3、重启TortoiseSVN 问题可能点2&#xff1a;注册表图标顺序太靠下&#xff0c;被占用 1、windowsr, 输入regedit进入注册表 2、找到一下目录 计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Cu…

基于微信小程序的奶茶点餐小程序设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言系统主要功能&#xff1a;具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计…

flink集群与资源@k8s源码分析-总述

1 简介 集群和资源模块提供动态资源能力,是分布式系统关键基础设施,分布式datax,分布式索引,事件引擎都需要集群和资源的弹性资源能力,提高伸缩性和作业处理能力。本文分析flink的集群和资源的k8s模块,深入了解其设计原理,为开发自有的集群和资源组件做技术准备, 同时涉…

云计算与大数据——部署Hadoop集群并运行MapReduce集群(超级详细!)

云计算与大数据——部署Hadoop集群并运行MapReduce集群(超级详细&#xff01;) Linux搭建Hadoop集群(CentOS7hadoop3.2.0JDK1.8Mapreduce完全分布式集群) 本文章所用到的版本号&#xff1a; CentOS7 Hadoop3.2.0 JDK1.8 基本概念及重要性 很多小伙伴部署集群用hadoop用mapr…

运动控制:音圈电机

在运动平台中&#xff0c;对于微小运动&#xff0c;例如1-5毫米&#xff0c;甚至更小的行程&#xff0c;常用音圈电机来驱动。 因为它们具有体积小&#xff0c;运动质量小&#xff0c;高加速度等显著特征。 无论是在工业领域&#xff0c;还是在医用内窥镜&#xff0c;呼吸机&…

python - 超详细实现 csv 文件单个、批量读取和输出功能,读取数据并保存导出为 csv 文件教程(详细示例源码,一键复制开箱即用)

介绍 实现了在python中,cvs文件的单个或批量读取,以及导出输出详细示例代码教程,新手小白一看就懂! 简单改下代码,就可以轻松用到你的项目中去了。 示例源码 按照以下示例代码,完成复制。<

Linux服务器自定义登陆提示信息

背景 最近在搭建zookeeper和应用服务环境&#xff0c;需要配置很多东西&#xff0c;然后不同服务器的文件路径之类的东西可能会有一些不同&#xff0c;比较麻烦&#xff0c;就准备给每个服务器配置一个登陆提示&#xff0c;让每一个登陆的用户能很快了解配置信息和文件路径。 …

2023年9月28日历史上的今天大事件早读

公元前551年9月28日 孔子诞辰 1864年9月28日 第一国际成立 1868年9月28日 上海江南制造总局第一号火轮船竣工 1898年9月28日 “戊戌六君子”被处死 1908年9月28日 十三世达赖抵京 1927年9月28日 汾水战役 1928年9月28日 崇安起义 1945年9月28日 中国军队赴越南接受日军投降 195…

写代码生成流程图

我们在写文档&#xff0c;博客的时候&#xff0c;一般都会使用markdown语法&#xff0c;最常见的就是一些github开源项目的README。有时候会去画一些流程图&#xff0c;例如使用process.on或者xmind等第三方网站&#xff0c;然后截图插入到文档中。 今天我们介绍一种使用代码直…

Podfile文件对ios,osx的支持

def import_podspod CoreKit endtarget :ios doplatform :ios, 7.0import_pods endtarget :osx doplatform :osx, 10.9import_pods end

AI AIgents时代 - (四.) HuggingGPT MetaGPT

&#x1f7e2; HuggingGPT HuggingGPT是一个多模型调用的 Agent 框架&#xff0c;利用 ChatGPT 作为任务规划器&#xff0c;根据每个模型的描述来选择 HuggingFace 平台上可用的模型&#xff0c;最后根据模型的执行结果生成总结性的响应。 这个项目目前已在 Github 上开源&am…

python:数据拟合求解方程参数

大家早好、午好、晚好吖 ❤ ~欢迎光临本文章 如果有什么疑惑/资料需要的可以点击文章末尾名片领取源码 首先引入三件套和scipy import numpy as np import pandas as pd import matplotlib.pyplot as plt from scipy.optimize import curve_fit拿到实验数据,通过pandas读取为…

‘Could not find first log file name in binary log index file‘的解决办法

mysql主从报异常Got fatal error 1236 from master when reading data from binary log: Could not find first log file name in binary log index file 数据库主从出错: Slave_IO_Running: No 一方面原因是因为网络通信的问题也有可能是日志读取错误的问题。以下是日志出错…

知识图谱02——使用python将信息录入neo4j

将文档传入chatgpt&#xff0c;生成对应的cypher语句 链接: https://pan.baidu.com/s/1Ny-ttbBSpqYEigwYiCWMeA?pwdc7sc 提取码: c7sc 使用命令行安装对应的包 pip install neo4jchatgpt生成出的txt文档中的内容如下&#xff1a; MERGE (Node1:Entity {name: 原始舱单提运单…

ClickHouse(15)ClickHouse合并树MergeTree家族表引擎之GraphiteMergeTree详细解析

GraphiteMergeTree该引擎用来对Graphite数据(图数据)进行瘦身及汇总。对于想使用ClickHouse来存储Graphite数据的开发者来说可能有用。 如果不需要对Graphite数据做汇总&#xff0c;那么可以使用任意的ClickHouse表引擎&#xff1b;但若需要&#xff0c;那就采用GraphiteMerge…

实验室没人导该怎么办

实验室没人教该怎么办 Q: 国内top5高校研一,课题开始老板就给了一个大方向,之后怎么做实验都是自己看文献研究的,终于开始动手做实验,才发现别人根本不想管你,宁愿抱着电脑看剧也不想教你,十分焦虑,该怎么办? A: 按照大多数实验室的惯例,老板一定会指派一个小老板…

电子学会Python二级知识点(自己整理)

序列 Python的变量不需要声明&#xff0c;每个变量在使用之前必须赋值&#xff0c;变量被赋值以后&#xff0c;该变量才会被创建。常见的6个数据类型&#xff1a;数字(Number)、字符串(String)、列表(List)、元组(Tuple)、集合(Set)、字典(Dictionary)。6中数据类型分为两大类…

解决键盘长按才有反应

问题分析&#xff1a; 排除键盘自身没有问题&#xff0c;那就应该是电脑设置的问题&#xff0c;目前我遇到的不小心长按shift键设置了【筛选键】 解决方式&#xff1a; 打开设置搜索筛选建&#xff0c;关闭&#xff0c;粘带键也会出现类似问题。