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

golang学习笔记22——golang微服务中数据竞争问题及解决方案

  • 推荐学习文档
    • golang应用级os框架,欢迎star
    • golang应用级os框架使用案例,欢迎star
    • 案例:基于golang开发的一款超有个性的旅游计划app经历
    • golang实战大纲
    • golang优秀开发常用开源库汇总
    • 想学习更多golang知识,这里有免费的golang学习笔记专栏

文章目录

    • 引言
    • 什么是数据竞争
    • 数据竞争产生的原因
      • 1.共享数据的并发访问
    • 数据竞争的危害
      • 1.数据不一致
    • 解决数据竞争的方案
      • 1.使用互斥锁(sync.Mutex)
      • 2.使用读写锁(sync.RWMutex)
      • 3.使用原子操作(sync/atomic)
    • 总结

引言

在 Golang 构建的微服务架构中,多个协程并发执行是常见的场景。然而,这种并发操作如果处理不当,很容易导致数据竞争问题,影响微服务的稳定性和正确性。本文将详细探讨数据竞争问题的产生原因、危害以及解决方案,并通过代码示例进行说明。

什么是数据竞争

数据竞争(Data Race)是指在多个协程同时访问和操作共享数据时,至少有一个是写操作,且没有正确的同步机制来保证数据的一致性。

数据竞争产生的原因

1.共享数据的并发访问

  • 在微服务中,多个协程可能需要共享一些全局变量或者公共的数据结构。例如,一个计数器用于统计微服务接收到的请求数量,多个协程都可能对这个计数器进行读写操作。
  • 代码示例:
package mainimport ("fmt""sync"
)var count intfunc increment() {count++
}func main() {var wg sync.WaitGroupfor i := 0; i < 1000; i++ {wg.Add(1)go func() {increment()wg.Done()}()}wg.Wait()// 最终结果可能小于 1000fmt.Println("Count:", count)
}

在上述代码中,多个协程同时对全局变量count进行自增操作,由于没有同步机制,就会产生数据竞争。

数据竞争的危害

1.数据不一致

  • 数据可能出现不可预测的值,导致微服务的业务逻辑出现错误。例如,在一个库存管理微服务中,如果多个协程同时处理订单,对库存数量进行操作,可能会导致库存数量出现负数等不合理的值。
  • 代码示例(模拟库存管理):
package mainimport ("fmt""sync"
)var inventory int = 100func processOrder(quantity int) {// 模拟处理订单,减少库存if inventory >= quantity {inventory -= quantity} else {fmt.Println("库存不足")}
}func main() {var wg sync.WaitGroupfor i := 0; i < 10; i++ {wg.Add(1)go func() {processOrder(10)wg.Done()}()}wg.Wait()// 可能出现库存数量不合理的情况fmt.Println("Inventory:", inventory)
}

解决数据竞争的方案

1.使用互斥锁(sync.Mutex)

  • 原理
    • 互斥锁可以确保在同一时刻只有一个协程能够访问被保护的共享数据。
  • 代码示例(改进计数器):
package mainimport ("fmt""sync"
)var count int
var mutex sync.Mutexfunc increment() {mutex.Lock()count++mutex.Unlock()
}func main() {var wg sync.WaitGroupfor i := 0; i < 1000; i++ {wg.Add(1)go func() {increment()wg.Done()}()}wg.Wait()// 结果正确为 1000fmt.Println("Count:", count)
}

2.使用读写锁(sync.RWMutex)

  • 原理
    • 当有多个协程同时读取共享数据时,可以同时进行,而当有写操作时,需要独占访问。适用于读多写少的场景。
  • 代码示例(模拟配置文件读取和更新):
package mainimport ("fmt""sync""time"
)// 模拟配置文件内容
var configData string = "default config"
var rwMutex sync.RWMutex// 读取配置的函数
func readConfig() {rwMutex.RLock()fmt.Println("Reading config:", configData)rwMutex.RUnlock()
}// 更新配置的函数
func updateConfig(newConfig string) {rwMutex.Lock()configData = newConfigfmt.Println("Updating config to:", configData)rwMutex.Unlock()
}func main() {var wg sync.WaitGroup// 多个协程读取配置for i := 0; i < 5; i++ {wg.Add(1)go func() {readConfig()wg.Done()}()}// 一个协程更新配置wg.Add(1)go func() {time.Sleep(2 * time.Second)updateConfig("new config")wg.Done()}()wg.Wait()
}

3.使用原子操作(sync/atomic)

  • 原理
    • 原子操作是在底层硬件上保证操作的原子性,无需使用锁,性能更高,但适用场景相对有限。
  • 代码示例(改进计数器):
package mainimport ("fmt""sync""sync/atomic"
)var atomicCount int32func atomicIncrement() {atomic.AddInt32(&atomicCount, 1)
}func main() {var wg sync.WaitGroupfor i := 0; i < 1000; i++ {wg.Add(1)go func() {atomicIncrement()wg.Done()}()}wg.Wait()// 结果正确为 1000fmt.Println("Atomic Count:", atomicCount)
}

总结

在 Golang 微服务开发中,数据竞争是一个必须高度重视的问题。通过合理使用互斥锁、读写锁和原子操作等同步机制,可以有效地避免数据竞争,确保微服务的稳定运行和数据的一致性。

关注我看更多有意思的文章哦!👉👉

相关文章:

golang学习笔记22——golang微服务中数据竞争问题及解决方案

推荐学习文档 golang应用级os框架&#xff0c;欢迎stargolang应用级os框架使用案例&#xff0c;欢迎star案例&#xff1a;基于golang开发的一款超有个性的旅游计划app经历golang实战大纲golang优秀开发常用开源库汇总想学习更多golang知识&#xff0c;这里有免费的golang学习笔…...

yolo训练出现Could not load library libcudnn_cnn_train.so.8问题及解决方法

问题场景&#xff1a; 训练yolov5或者yolov8时候会报错&#xff1a; Could not load library libcudnn_cnn_train.so.8. Error: /usr/local/cuda-12.1/lib64/libcudnn_cnn_train.so.8: uined symbol: _ZN5cudnn3cnn34layerNormFwd_execute_internal_implERKNS_7backend11Vari…...

携手科大讯飞丨云衔科技为企业提供全栈AI技术解决方案

作为智能时代的核心驱动力&#xff0c;人工智能不仅重塑了传统行业的面貌&#xff0c;更开辟了全新的经济增长点。科大讯飞以其深厚的技术底蕴和创新能力&#xff0c;持续引领着人工智能领域的发展潮流。云衔科技作为科大讯飞开放平台的AI技术产品线合作伙伴代理商&#xff0c;…...

57页PPT | 智慧文旅整体建设解决方案

主要介绍了智慧文旅的建设背景、需求分析、解决方案、应用系统功能需求、客户价值、企业价值、建设理念、建设思路、总体架构、安全管理体系、融媒体综合服务平台、大数据分析平台、智慧文旅云平台、智慧管理、智慧营销、智慧服务等方面的内容。 背景及需求分析 方案架构及理念…...

线性代数之QR分解和SVD分解

文章目录 1.QR分解Schmidt正交化Householder变换QR分解的应用 2. 求矩阵特征值、特征向量的基本方法3.SVD分解SVD分解的应用 参考文献 1.QR分解 矩阵的正交分解又称为QR分解&#xff0c;是将矩阵分解为一个正交矩阵Q和一个上三角矩阵R的乘积的形式。 任意实数方阵A&#xff0c…...

在虚拟机安装mysql数据库

一、安装步骤&#xff08;下载包-传输软件包-安装包-启用仓库-使用yum安装服务器&#xff09; 1、要在mysql官网下载yum仓库包 2、下载好rpm包后&#xff0c;将其通过xftp传输到root目录下 3、使用sudo yum install yum的仓库名&#xff08;sudo yum install mysql-community-…...

详解QT插件机制

Qt插件机制允许将功能模块化为独立的插件,从而在运行时动态加载和卸载这些模块。这种机制对于扩展应用程序、插件架构和动态功能添加非常有用 插件机制 插件的基本概念 插件: 在Qt中,插件是实现特定接口的动态库(DLL或so文件),这些接口由Qt插件框架定义。插件可以被应用程序…...

【Hot100】LeetCode—32. 最长有效括号

目录 1- 思路题目识别动态规划 2- 实现⭐32. 最长有效括号——题解思路 3- ACM 实现 原题链接&#xff1a;32. 最长有效括号 1- 思路 题目识别 识别1 &#xff1a;给定一个字符串 s &#xff0c;求解 s 中的最长有效括号 动态规划 动态规划五部曲 递推公式难如果遇到了 s.…...

力扣198-打家劫舍

你是一个专业的小偷&#xff0c;计划偷窃沿街的房屋。每间房内都藏有一定的现金&#xff0c;影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统&#xff0c;如果两间相邻的房屋在同一晚上被小偷闯入&#xff0c;系统会自动报警。 给定一个代表每个房屋存放金额的…...

Python 入门教程(4)数据类型 | 4.1、数据类型

文章目录 一、数据类型1、弱类型与强类型2、变量没有类型&#xff0c;数据有类型3、不可变类型和可变类型 前言&#xff1a; Python 是一种高级编程语言&#xff0c;以其简洁的语法、丰富的内置库和动态类型系统而闻名。在 Python 中&#xff0c;数据类型是编程的基础&#xff…...

如何进行DAP-seq的数据挖掘,筛选验证位点

从样本准备到寄送公司&#xff0c;每一天都在“祈祷”有个心仪的分析结果&#xff0c;终于在这天随着邮件提示音的响起&#xff0c;收到了分析结果...... 分析前工作 爱基在进行数据分析之前&#xff0c;会有两次质控报告反馈给老师们。第一个&#xff0c;基因组DNA的提取质控…...

学习大数据DAY56 业务理解和第一次接入

作业1 1 了解行业名词 ERP CRM OA MES WMS RPA SAAS 了解每个系统的功能和应用 ERP 系统&#xff0c;&#xff08;Enterprise Resource Planning&#xff0c;企业资源计划系统&#xff09;&#xff1a;ERP 系统 是一种用于管理企业各类资源的软件系统&#xff0c;包括生产管理…...

java线程池编程示例

程序功能 这段代码展示了如何使用 Java 线程池 来并发执行多个任务。通过创建一个固定大小为 3 的线程池&#xff0c;程序提交了 5 个任务&#xff0c;并让线程池中的线程并发处理这些任务。每个任务模拟了一个耗时操作&#xff0c;最后程序等待所有任务完成后关闭线程池。 …...

02 基于STM32的按键控制继电器驱动电机

本专栏所有源资料都免费获取&#xff0c;没有任何隐形消费。 注意事项&#xff1a;STM32仿真会存在各种各样BUG&#xff0c;且尽量按照同样仿真版本使用。本专栏所有的仿真都采用PROTEUS8.15。 本文已经配置好STM32F103C8T6系列&#xff0c;在PROTUES仿真里&#xff0c;32单片…...

网页本地存储

网页本地存储 <html> <script>//添加数据function add(){var text;textdocument.getElementById(text).value;indexlocalStorage.length1;localStorage.setItem(index,text);}//显示localStorage所有内容function showall(){storagelocalStorage;var length stor…...

SpringBoot2:web开发常用功能实现及原理解析-@ControllerAdvice实现全局异常统一处理

文章目录 前言1、工程包结构2、POM依赖3、Java代码 前言 本篇主要针对前后端分离的项目&#xff0c;做的一个统一响应包装、统一异常捕获处理。 在Spring里&#xff0c;我们可以使用ControllerAdvice来声明一些关于controller的全局性的东西&#xff0c;其用法主要有以下三点…...

DockerLinux安装DockerDocker基础

Linux软件安装 yum命令安装 通过yum命令安装软件,是直接把软件安装到Linux系统中 安装和卸载都比较麻烦,因为软件和系统是强关联的 Docker docker是一种容器技术,可以解决软件和系统强关联关系,使得软件的安装和卸载更方便,它可以将我们的应用以及依赖进行打包,制作出一个镜…...

macOS平台TensorFlow环境安装

1.安装xtarfile pip3 install xtarfile 2.安装 pip3 install matplotlib 3.安装jieba pip3 install jieba 4.安装 pip3 install tensorflow tensorflow安装成功...

全网最全 线程邮箱

线程邮箱的优缺点 优点 避免资源竞争&#xff1a;线程邮箱通过队列和互斥锁来管理线程间的通信&#xff0c;确保只有持有锁的线程可以访问和修改队列中的数据&#xff0c;从而避免了多个线程同时尝试修改同一资源时可能出现的竞争条件&#xff0c;减少了因资源竞争导致的死锁…...

Linux下rpm方式部署mysql(国产化生产环境无联网服务器部署实操)

请放心观看&#xff0c;已在正式环境部署验证&#xff0c;流程无问题&#xff01; 所用系统为国产化麒麟银河 aarch64系统&#xff0c;部署时间2024年9月份&#xff01; #查看服务器信息 #涉及生产服务器&#xff0c;所以输出信息隐藏了一部分[rootecs-xxxxx hdata]# uname -…...

Spark 之 入门讲解详细版(1)

1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室&#xff08;Algorithms, Machines, and People Lab&#xff09;开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目&#xff0c;8个月后成为Apache顶级项目&#xff0c;速度之快足见过人之处&…...

FFmpeg 低延迟同屏方案

引言 在实时互动需求激增的当下&#xff0c;无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作&#xff0c;还是游戏直播的画面实时传输&#xff0c;低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架&#xff0c;凭借其灵活的编解码、数据…...

大数据零基础学习day1之环境准备和大数据初步理解

学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 &#xff08;1&#xff09;设置网关 打开VMware虚拟机&#xff0c;点击编辑…...

蓝桥杯 2024 15届国赛 A组 儿童节快乐

P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡&#xff0c;轻快的音乐在耳边持续回荡&#xff0c;小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下&#xff0c;六一来了。 今天是六一儿童节&#xff0c;小蓝老师为了让大家在节…...

Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务

通过akshare库&#xff0c;获取股票数据&#xff0c;并生成TabPFN这个模型 可以识别、处理的格式&#xff0c;写一个完整的预处理示例&#xff0c;并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务&#xff0c;进行预测并输…...

第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明

AI 领域的快速发展正在催生一个新时代&#xff0c;智能代理&#xff08;agents&#xff09;不再是孤立的个体&#xff0c;而是能够像一个数字团队一样协作。然而&#xff0c;当前 AI 生态系统的碎片化阻碍了这一愿景的实现&#xff0c;导致了“AI 巴别塔问题”——不同代理之间…...

ElasticSearch搜索引擎之倒排索引及其底层算法

文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...

C++中string流知识详解和示例

一、概览与类体系 C 提供三种基于内存字符串的流&#xff0c;定义在 <sstream> 中&#xff1a; std::istringstream&#xff1a;输入流&#xff0c;从已有字符串中读取并解析。std::ostringstream&#xff1a;输出流&#xff0c;向内部缓冲区写入内容&#xff0c;最终取…...

【服务器压力测试】本地PC电脑作为服务器运行时出现卡顿和资源紧张(Windows/Linux)

要让本地PC电脑作为服务器运行时出现卡顿和资源紧张的情况&#xff0c;可以通过以下几种方式模拟或触发&#xff1a; 1. 增加CPU负载 运行大量计算密集型任务&#xff0c;例如&#xff1a; 使用多线程循环执行复杂计算&#xff08;如数学运算、加密解密等&#xff09;。运行图…...

什么是Ansible Jinja2

理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具&#xff0c;可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板&#xff0c;允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板&#xff0c;并通…...