golang 确保并发安全性

golang并发安全性

在Golang中,并发安全性通常指的是当多个goroutines同时访问同一个数据结构或资源时,能够保证数据的一致性和完整性,避免数据竞争、死锁等问题

并发安全性案例

案例1

创建 count,起1000个goroutines,做一亿次自增运算,代码如下:

func main() {wg := sync.WaitGroup{}var count = 0for i := 0; i < 1000; i++ {wg.Add(1)go func() {defer wg.Done()for i := 0; i < 10000; i++ {count++}}()}wg.Wait()fmt.Println(count)
}

预计结果:

100000000

执行结果:

test go run main.go 
656188

原因:

count++非原子性操作,在串行场景下,不会出现一致性问题,但是在并发场景下,多个goroutines并发操作同一个变量,就会出现goroutinescount值相互覆盖的情况,导致一致性问题

案例2

通过rpc接口,并行多次数据请求,并把返回结果做整合

func main() {wg := sync.WaitGroup{}var list []intfor i := 0; i < 1000; i++ {wg.Add(1)go func() {defer wg.Done()// rpc请求,结果并进行整合list = append(list, rpcCall()...)}()}wg.Wait()fmt.Println(len(list))
}// rpc 调用
func rpcCall() []int {var ret []intfor i := 0; i < 100; i++ {ret = append(ret, rand.Intn(10000))}return ret
}

预计结果:

100000

执行结果:

test go run main.go 
21500

append 方法不是原子操作,并发情况下存在一致性问题

解决办法

  • 使用互斥锁(Mutex):通过使用互斥锁来保护共享资源的访问,一次只允许一个goroutine访问共享资源,从而避免竞争条件
  • 使用原子操作(Atomic Operations):对于简单的读写操作,可以使用原子操作来保证操作的原子性,避免竞争条件
  • 使用通道(Channel):通过使用通道来进行goroutine之间的通信和同步,避免共享资源的直接访问
  • 使用并发安全的数据结构,例如 sync.Map等
案例1 优化方案

通过共享锁解决问题:

func main() {// 添加互斥锁mu := sync.Mutex{}wg := sync.WaitGroup{}var count = 0for i := 0; i < 1000; i++ {wg.Add(1)go func() {defer wg.Done()for i := 0; i < 10000; i++ {// 锁住共享资源mu.Lock()count++mu.Unlock()}}()}wg.Wait()fmt.Println(count)
}

执行结果:

test go run main.go 
10000000

通过原子操作解决问题:

func main() {wg := sync.WaitGroup{}var count int32 = 0for i := 0; i < 1000; i++ {wg.Add(1)go func() {defer wg.Done()for i := 0; i < 10000; i++ {atomic.AddInt32(&count, 1)}}()}wg.Wait()fmt.Println(count)
}

执行结果:

test go run main.go 
10000000
案例2 优化方案

通过channel + select-case解决问题

func main() {// 创建channelch := make(chan []int, 100)var list []intfor i := 0; i < 1000; i++ {go func(ch chan []int) {// rpc结果写入channel中ch <- rpcCall()}(ch)}// 轮询等待每个goroutine的执行结果for i := 0; i < 1000; i++ {select {case v := <-ch:list = append(list, v...)}}fmt.Println(len(list))
}// rpc 调用
func rpcCall() []int {var ret []intfor i := 0; i < 100; i++ {ret = append(ret, rand.Intn(10000))}return ret
}

执行结果:

test go run main.go 
100000

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

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

相关文章

Java中自定义异常指南

在Java编程中&#xff0c;异常处理是一个非常重要的部分&#xff0c;它允许我们在程序运行时捕获和处理错误情况。除了Java标准库提供的异常类外&#xff0c;我们还可以根据实际需要创建自定义的异常类。自定义异常可以帮助我们更好地描述和处理特定的错误情况。下面&#xff0…

【python的魅力】:教你如何用几行代码实现文本语音识别

文章目录 引言一、运行效果二、文本转换为语音2.1 使用pyttsx32.2 使用SAPI实现文本转换语音2.3 使用 SpeechLib实现文本转换语音 三、语音转换为文本3.1 使用 PocketSphinx实现语音转换文本 引言 语音识别技术&#xff0c;也被称为自动语音识别&#xff0c;目标是以电脑自动将…

Tomcat启动闪退怎么解决(文末附终极解决方案)

AI是这么告诉我的 Tomcat启动时出现闪退问题可能由多种原因引起&#xff0c;以下是解决此类问题的一些通用方法&#xff1a; 检查环境变量&#xff1a; 确保已经正确设置了JAVA_HOME和JRE_HOME环境变量&#xff0c;并指向正确的Java安装路径。将Java的bin目录添加到系统的PATH…

c语言题目

一些关于c语言的题目 文章目录 一、计算程序输出二、以下程序运行时&#xff0c;若输入1abcedf2df<回车>输出结果是将flag的第二个bit置0结构体大小下列C程序执行后c输出结果为&#xff08;&#xff09;设有定义char *p[]{"Shanghai","Beijing",&quo…

使用独立的 centos 7 安装软件后 commit 为新的镜像并自启动进程

使用独立的 centos 7 安装软件后 commit 为新的镜像&#xff0c;在 dockerfile 里通过添加 CMD ["/usr/sbin/init"] 这个命令来实现程序在容器中的开机自启动&#xff0c;并在 docker run 时添加参数 --privileged 获取容器内真正的 root 权限。 在 docker run 命令…

英语四级备考之名词的定义

名词是人、动物、事物、地方、状态、品质或动作的名称。它可以 表示具体的东西&#xff0c;也可表示抽象的东西。下面斜体字都是名词&#xff1a; John is my friend&#xff0e;My children love their teachers&#xff0e;&#xff08;人&#xff09; The dog is running a…

富格林:细节决定能否安全出金

富格林悉知&#xff0c;投资者都希望在现货黄金交易市场中获利&#xff0c;但并非所有投资者都能实现获利的心愿&#xff0c;有时候忽略一些细节问题也会影响最终的投资效果。投资者应该注重细节实现安全出金才是我们进行投资的最终目标。下面富格林将总结一些注重细节实现安全…

scikit-learn:Python中的机器学习-1

简介&#xff1a;问题设置 什么是机器学习&#xff1f; 机器学习是关于构建具有可调参数的程序&#xff0c;这些参数可以自动调整&#xff0c;以便通过适应先前看到的数据来改善其行为。机器学习可以被认为是人工智能的一个子领域&#xff0c;因为这些算法可以被视为构建模块…

Python量化炒股的获取数据函数—get_index_stocks()

Python量化炒股的获取数据函数—get_index_stocks() 利用get_industry_stocks()函数可以获取在给定日期一个行业的所有股票代码列表&#xff0c;其语法格式如下&#xff1a; get_industry_stocks(industry_code, dateNone)各项参数的意义 参数date和返回值&#xff0c;都与g…

你知道什么是Charles吗?

什么是Charles? Charles中文名叫青花瓷&#xff0c;它是一款基于HTTP协议的代理服务器&#xff0c;通过成为电脑或者浏览器的代理&#xff0c;然后截取请求和请求结果达到分析抓包的目的。它跨平台、半免费&#xff0c;与免费版本不同的是&#xff0c;半免费版本的Charles重启…

八、Linux进程检测与控制

章节目标 了解进程和程序的关系了解进程的特点能够使用top动态查看进程信息能够使用ps静态查看进程信息能够使用kill命令给进程发送信号能够调整进程的优先级&#xff08;扩展&#xff09; 引言 在运维的日常工作中&#xff0c;监视系统的运行状况是每天例行的工作&#xff…

PPT基础

5种ppt仅可读形式 Ⅰ 开始选项卡 1.【幻灯片】组中&#xff1a;新建幻灯片&#xff0c;从大纲中导入幻灯片&#xff1b;修改幻灯片的版式&#xff1b;节&#xff08;新增节&#xff0c;重命名节&#xff09;。 2.【字体】组中&#xff1a;设置字体&#xff0c;字体大小&…

docker-compose启动mysql5.7报错

描述一下问题经过&#xff1a; 使用docker compose 部署mysql5.7 文件如下: services:mysql:restart: alwaysimage: mysql:5.7container_name: mysql-devports:- 3306:3306environment:- MYSQL_DATABASEdev- MYSQL_ROOT_PASSWORD123456healthcheck:test: ["CMD", &q…

《21天学通C++》(第十六章)STL string类

为什么需要string类&#xff1f; 1.减少在创建和操作字符串方面的操作 2.在内部管理内存分配细节&#xff0c;提高程序稳定性 3.提供复制构造函数和赋值运算符 4.提供截短、查找、删除、比较等函数 1.实例化STL string #include <iostream>int main() {std::string strS…

Python+PYGObject/PYGtk+CSS样式--2024python示例

隔久点不用老是会忘&#xff0c;留个笔记。。 PythonPYGObject/PYGtk&#xff0c;加载 CSS 样式的演示代码 demo 运行的效果截图&#xff1a; #!/usr/bin/env python3 import sys import gigi.require_version("Gtk", "3.0") from gi.repository import …

Linux驱动开发——(十)MISC设备驱动

目录 一、MISC驱动介绍 1.1 miscdevice结构体 1.2 misc_register函数 1.3 misc_deregister函数 二、驱动代码 2.1 框架代码流程 2.2 完整框架代码 一、MISC驱动介绍 MISC驱动&#xff08;杂项驱动&#xff09;&#xff0c;当板子上的某些外设无法进行分类的时候就可以使…

每日一算法

问题 等待登机的你看着眼前有老有小长长的队伍十分无聊&#xff0c;你突然 想要知道&#xff0c;是否存在两个年龄相仿的乘客。每个乘客的年龄用 1个0 到 36500 的整数表示&#xff0c;两个乘客的年龄相差 365 以内 就认为是相仿的。 具体来说&#xff0c;你有一个长度为 n 的…

c#使用Elastic.Clients.Elasticsearch 库进行ElasticSearch的增删改查操作,根据变量动态构建查询条件。

实体类Shop结构: public class Shop {public string UUID { set; get; }public string ItemType { set; get; }public long ItemId { set; get; }public string ItemName { set; get; }public long Gold { set; get; }public long Number { set; get; }public string Data { s…

进程控制【Linux】

文章目录 进程终止进程等待 创建一批子进程 #include <stdio.h> #include <unistd.h> #include <stdlib.h> #define N 5void runChild() {int cnt 10;while (cnt ! 0){printf("i am a child : %d , ppid:%d\n", getpid(), getppid());sleep(1);c…

【后端】RabbitMQ的常见使用问题

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、RabbitMQ 常见问题二、RabbitMQ 常见报错三、总结 前言 例如&#xff1a;随着人工智能的不断发展&#xff0c;机器学习这门技术也越来越重要&#xff0c;很…