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

golang学习笔记11——Go 语言的并发与同步实现详解

  • 推荐学习文档
    • 基于golang开发的一款超有个性的旅游计划app经历
    • golang实战大纲
    • golang优秀开发常用开源库汇总
    • golang学习笔记01——基本数据类型
    • golang学习笔记02——gin框架及基本原理
    • golang学习笔记03——gin框架的核心数据结构
    • golang学习笔记04——如何真正写好Golang代码?
    • golang学习笔记05——golang协程池,怎么实现协程池?
    • golang学习笔记06——怎么实现本地文件及目录监控-fsnotify
    • golang学习笔记07——使用gzip压缩字符减少redis等存储占用的实现
    • golang学习笔记08——如何调用阿里oss sdk实现访问对象存储?
    • golang学习笔记09——golang优秀开发常用开源库汇总
    • golang学习笔记10——golang 的 Gin 框架,快速构建高效 Web 应用

文章目录

    • 引言
    • Go 语言的并发模型
      • 1.goroutine
      • 2.channel
    • Go 语言的同步机制
      • 1.mutex
      • 2.wait group
    • 总结

引言

在现代软件开发中,并发和同步是非常重要的概念。Go 语言以其简洁高效的并发模型而备受关注。本文将详细介绍 Go 语言中并发与同步的实现方式,并结合代码示例进行深入讲解。

Go 语言的并发模型

1.goroutine

  • Goroutine 是 Go 语言中实现并发的轻量级线程。与传统的线程相比,goroutine 占用的内存更少,创建和切换的开销也更小。
  • 创建 goroutine 非常简单,只需要在函数调用前加上 go 关键字即可。例如:
package mainimport ("fmt""time"
)func printNumbers() {for i := 1; i <= 5; i++ {fmt.Println(i)time.Sleep(time.Millisecond * 500)}
}func main() {go printNumbers()fmt.Println("Main function")time.Sleep(time.Second * 2)
}

在上面的代码中,printNumbers 函数会在一个新的 goroutine 中执行,而 main 函数会继续执行。这样就实现了并发执行两个任务。

2.channel

  • channel 是用于 goroutine 之间通信的机制。它可以在不同的 goroutine 之间传递数据,实现同步和协调。
  • 创建 channel 可以使用 make 函数。例如:ch := make(chan int) 创建了一个整数类型的 channel。
  • 可以使用 <- 操作符从 channel 中接收数据或向 channel 中发送数据。例如:
package mainimport ("fmt"
)func sendData(ch chan int) {for i := 1; i <= 5; i++ {ch <- i}close(ch)
}func main() {ch := make(chan int)go sendData(ch)for num := range ch {fmt.Println(num)}
}

在上面的代码中,sendData 函数会向 channel 中发送数据,而 main 函数会从 channel 中接收数据。当 sendData 函数发送完所有数据后,会关闭 channel。main 函数中的 for range 循环会自动检测 channel 的关闭,并退出循环。

Go 语言的同步机制

1.mutex

  • mutex(互斥锁)是一种用于保护共享资源的同步机制。在 Go 语言中,可以使用 sync.Mutex 类型来实现互斥锁。
  • 使用互斥锁的步骤如下:
    • 创建一个 sync.Mutex 类型的变量。
    • 在需要保护的代码块前,调用 Lock 方法获取锁。
    • 在代码块执行完毕后,调用 Unlock 方法释放锁。
  • 例如:
package mainimport ("fmt""sync"
)var counter int
var mutex sync.Mutexfunc increment() {mutex.Lock()defer mutex.Unlock()counter++fmt.Println(counter)
}func main() {for i := 0; i < 5; i++ {go increment()}// 等待所有 goroutine 执行完毕time.Sleep(time.Second)
}

在上面的代码中,increment 函数会对共享变量 counter 进行加一操作。为了避免多个 goroutine 同时访问和修改 counter 变量,使用了互斥锁 mutex。在 increment 函数中,首先调用 Lock 方法获取锁,然后对 counter 进行加一操作,最后调用 Unlock 方法释放锁。

2.wait group

  • WaitGroup 是一种用于等待一组 goroutine 执行完毕的同步机制。在 Go 语言中,可以使用 sync.WaitGroup 类型来实现 WaitGroup。
  • 使用 WaitGroup 的步骤如下:
    • 创建一个 sync.WaitGroup 类型的变量。
    • 在每个需要等待的 goroutine 中,调用 Add 方法增加等待的 goroutine 数量。
    • 在 goroutine 执行完毕后,调用 Done 方法减少等待的 goroutine 数量。
    • 在主 goroutine 中,调用 Wait 方法等待所有 goroutine 执行完毕。
  • 例如:
package mainimport ("fmt""sync"
)func process(wg *sync.WaitGroup) {defer wg.Done()fmt.Println("Processing...")
}func main() {var wg sync.WaitGroupfor i := 0; i < 5; i++ {wg.Add(1)go process(&wg)}wg.Wait()fmt.Println("All processes completed.")
}

在上面的代码中,process 函数会模拟一个处理过程。在主 goroutine 中,创建了一个 sync.WaitGroup 类型的变量 wg。然后,在循环中启动了 5 个 goroutine,并在每个 goroutine 中调用 Add 方法增加等待的 goroutine 数量。在每个 goroutine 执行完毕后,会调用 Done 方法减少等待的 goroutine 数量。最后,在主 goroutine 中,调用 Wait 方法等待所有 goroutine 执行完毕。

总结

Go 语言的并发与同步机制使得开发者能够轻松地编写高效的并发程序。通过 goroutine 和 channel,开发者可以实现轻量级的并发编程,提高程序的性能和响应速度。同时,通过 mutex 和 wait group 等同步机制,开发者可以保护共享资源,确保程序的正确性。在实际开发中,开发者可以根据具体的需求选择合适的并发和同步机制,以实现高效、可靠的程序。

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

相关文章:

golang学习笔记11——Go 语言的并发与同步实现详解

推荐学习文档 基于golang开发的一款超有个性的旅游计划app经历golang实战大纲golang优秀开发常用开源库汇总golang学习笔记01——基本数据类型golang学习笔记02——gin框架及基本原理golang学习笔记03——gin框架的核心数据结构golang学习笔记04——如何真正写好Golang代码&…...

关于汽车加油是加200还是加满的思考

车子快开了1万公里了&#xff0c;每个月保险会送一个200-15的加油优惠券&#xff0c;所以之前一直是每次加200的习惯&#xff0c; 最近突然觉得经常去加油很麻烦&#xff0c;而且很浪费时间&#xff0c; 需要重新评估一下&#xff0c; 一次加200 or 一次加300 or 一次加满&am…...

C# 去掉字符串最后一个字符的5种方法

C# 去掉字符串最后一个字符的 5 种方法 &#xff08;1&#xff09;Substring string original "Hello!"; string result original.Substring(0, original.Length - 1); Console.WriteLine(result); // 输出: Hello &#xff08;2&#xff09;Remove string o…...

[Redis] Redis中的String类型

&#x1f338;个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 &#x1f3f5;️热门专栏: &#x1f9ca; Java基本语法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12615970.html?spm1001.2014.3001.5482 &#x1f355; Collection与…...

Transiting from CUDA to HIP(三)

一、Workarounds 1. memcpyToSymbol 在 HIP (Heterogeneous-compute Interface for Portability) 中&#xff0c;hipMemcpyToSymbol 函数用于将数据从主机内存复制到设备上的全局内存或常量内存中&#xff0c;这样可以在设备端的内核中访问这些数据。这个功能特别有用&#x…...

基于SpringBoot+Vue+MySQL的垃圾分类回收管理系统

系统展示 用户界面 管理员界面 系统背景 二十一世纪互联网的出现&#xff0c;改变了几千年以来人们的生活&#xff0c;不仅仅是生活物资的丰富&#xff0c;还有精神层次的丰富。在互联网诞生之前&#xff0c;地域位置往往是人们思想上不可跨域的鸿沟&#xff0c;信息的传播速度…...

游戏的3C,Al

在游戏开发中&#xff0c;“3C”通常指的是三个重要的组成部分&#xff1a;Character&#xff08;角色&#xff09;、Camera&#xff08;摄像机&#xff09;和Control&#xff08;控制&#xff09;。这三者对于创建沉浸式和流畅的游戏体验至关重要。而AI&#xff08;人工智能&a…...

深度学习基础案例4--运用动态学习率构建CNN卷积神经网络实现的运动鞋识别(测试集的准确率84%)

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 前言 前几天一直很忙&#xff0c;一直在数学建模中&#xff0c;没有来得及更新&#xff0c;接下来将恢复正常这一次的案例很有意思&#xff1a;在学习动态调整…...

tekton pipeline workspaces

tekton pipeline workspace是一种为执行中的管道及其任务提供可用的共享卷的方法。 在pipeline中定义worksapce作为共享卷传递给相关的task。在tekton中定义workspace的用途有以下几点: 存储输入和/或输出在task之间共享数据secret认证的挂载点ConfigMap中保存的配置的挂载点…...

[git操作] git创建仓库上传github报错

操作流程如下 使用 git init使用 git remote add origin 项目ssh链接git add . 报错如下 Bus error (core dumped)然后执行任何别的操作都会报错&#xff1a; fatal: Unable to create path .. /.git/index.lock: File exists.Another git process seems to be running in …...

飞牛fnOS安装KDE桌面

飞牛fnOS安装KDE桌面 这段时间新出的nas系统飞牛os真不错&#xff0c;基于debian的可折腾性又高了不少&#xff0c;今天就来给这个系统装个桌面&#xff0c;插上显示器也能当个电脑自己进自己的管理界面&#xff0c;播放下视频&#xff0c;上上网啥的。 文章目录 飞牛fnOS安装…...

运维Tips | 如何安全的移除系统中旧的Linux内核?

[ 知识是人生的灯塔&#xff0c;只有不断学习&#xff0c;才能照亮前行的道路 ] 如何安全的删除系统中旧的 Linux 内核? 描述&#xff1a;如果更新了 Linux 操作系统&#xff0c;那么你会注意到&#xff0c;每次升级 Linux 内核后&#xff0c;GRUB 菜单都会添加一个新的引导条…...

基于JAVA+SpringBoot+Vue的工程教育认证的计算机课程管理平台

基于JAVASpringBootVue的工程教育认证的计算机课程管理平台 前言 ✌全网粉丝20W,csdn特邀作者、博客专家、CSDN[新星计划]导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末附源码下载链接…...

软件质量保障:故障演练介绍

目录 背景&#xff1a;架构变化带来的问题 什么是故障演练 为什么需要故障演练 故障演练场景有哪些 不同演练类型和目标 如何对工具进行评估 功能评测项 告警评测项 观测指标评测项 总结 背景&#xff1a;架构变化带来的问题 随着架构越来越复杂、应用越来越多样&…...

Vue3可编辑表格插件

插件亮点&#xff1a; 通过可自定义单元格内容。可控的状态控制&#xff0c;例如只读、禁止编辑行等配置。可控的状态交互&#xff0c;例如框选单元格、框选行等配置。可控的推拽顺序&#xff0c;例如拖拽行、推拽列。方便的单元格数据验证配置。方便的快捷右键菜单&#xff0c…...

RedisTemplate操作Redis

文章目录 1. String 命令1.1 添加缓存1.2 设置过期时间(单独设置)1.3 获取缓存值1.4 删除key1.5 顺序递增1.6 顺序递减1.7 常用的 2. Hash命令2.1 添加缓存2.2 设置过期时间(单独设置)2.3 添加一个Map集合2.4 提取所有的小key2.5 提取所有的value值2.6 根据key提取value值2.7 获…...

Web安全:SQL注入实战测试.(扫描 + 测试)

Web安全&#xff1a;SQL注入实战测试. SQL注入就是 有些恶意用户在提交查询请求的过程中 将SQL语句插入到请求内容中&#xff0c;同时程序的本身对用户输入的内容过于相信&#xff0c;没有对用户插入的SQL语句进行任何的过滤&#xff0c;从而直接被SQL语句直接被服务端执行&am…...

猜测、实现 B 站在看人数

猜测、实现 B 站在看人数 猜测找到接口参数总结 实现 猜测 找到接口 浏览器打开一个 B 站视频&#xff0c;比如 《黑神话&#xff1a;悟空》最终预告 | 8月20日&#xff0c;重走西游_黑神话悟空 (bilibili.com) &#xff0c;打开 F12 开发者工具&#xff0c;经过观察&#xf…...

网络编程(UDP)

UDP编程 UDP&#xff1a;全双工通信、面向无连接、不可靠 UDP&#xff08;User Datagram Protocol&#xff09;用户数据报协议&#xff0c;是不可靠的无连接的协议。在数据发送前&#xff0c;因为不需要进行连接&#xff0c;所以可以进行高效率的数据传输。 适用场景 发送小尺寸…...

CENet及多模态情感计算实战(论文复现)

CENet及多模态情感计算实战&#xff08;论文复现&#xff09; 本文所涉及所有资源均在传知代码平台可获取 文章目录 CENet及多模态情感计算实战&#xff08;论文复现&#xff09;概述研究背景主要贡献论文思路主要内容和网络架构数据集介绍性能对比复现过程&#xff08;重要&am…...

阿里云ACP云计算备考笔记 (5)——弹性伸缩

目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...

服务器硬防的应用场景都有哪些?

服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式&#xff0c;避免服务器受到各种恶意攻击和网络威胁&#xff0c;那么&#xff0c;服务器硬防通常都会应用在哪些场景当中呢&#xff1f; 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...

linux arm系统烧录

1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 &#xff08;忘了有没有这步了 估计有&#xff09; 刷机程序 和 镜像 就不提供了。要刷的时…...

Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析

Java求职者面试指南&#xff1a;Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问&#xff08;基础概念问题&#xff09; 1. 请解释Spring框架的核心容器是什么&#xff1f;它在Spring中起到什么作用&#xff1f; Spring框架的核心容器是IoC容器&#…...

Mysql8 忘记密码重置,以及问题解决

1.使用免密登录 找到配置MySQL文件&#xff0c;我的文件路径是/etc/mysql/my.cnf&#xff0c;有的人的是/etc/mysql/mysql.cnf 在里最后加入 skip-grant-tables重启MySQL服务 service mysql restartShutting down MySQL… SUCCESS! Starting MySQL… SUCCESS! 重启成功 2.登…...

云原生安全实战:API网关Kong的鉴权与限流详解

&#x1f525;「炎码工坊」技术弹药已装填&#xff01; 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 1. API网关&#xff08;API Gateway&#xff09; API网关是微服务架构中的核心组件&#xff0c;负责统一管理所有API的流量入口。它像一座…...

STM32---外部32.768K晶振(LSE)无法起振问题

晶振是否起振主要就检查两个1、晶振与MCU是否兼容&#xff1b;2、晶振的负载电容是否匹配 目录 一、判断晶振与MCU是否兼容 二、判断负载电容是否匹配 1. 晶振负载电容&#xff08;CL&#xff09;与匹配电容&#xff08;CL1、CL2&#xff09;的关系 2. 如何选择 CL1 和 CL…...

LangFlow技术架构分析

&#x1f527; LangFlow 的可视化技术栈 前端节点编辑器 底层框架&#xff1a;基于 &#xff08;一个现代化的 React 节点绘图库&#xff09; 功能&#xff1a; 拖拽式构建 LangGraph 状态机 实时连线定义节点依赖关系 可视化调试循环和分支逻辑 与 LangGraph 的深…...

C++实现分布式网络通信框架RPC(2)——rpc发布端

有了上篇文章的项目的基本知识的了解&#xff0c;现在我们就开始构建项目。 目录 一、构建工程目录 二、本地服务发布成RPC服务 2.1理解RPC发布 2.2实现 三、Mprpc框架的基础类设计 3.1框架的初始化类 MprpcApplication 代码实现 3.2读取配置文件类 MprpcConfig 代码实现…...