Go并发编程学习-class1

class1. Mutex 解决资源并发访问

在这里插入图片描述

基础概念

临界区概念:一个被共享的资源,可以被并发访问。通过Mutex互斥锁,可以限定临界区只能由一个线程获取。

  1. 根据不同情况,不同适用场景

●共享资源。并发地读写共享资源,会出现数据竞争(data race) 的问题,所以需要
Mutex、RWMutex 这样的并发原语来保护。
●任务编排。需要goroutine按照一定的规律执行,而goroutine之间有相互等待或者依赖
的顺序关系,我们常常使用WaitGroup或者Channel来实现。
●消息传递。信息交流以及不同的goroutine之间的线程安全的数据交流,常常使用
Channel来实现。

  1. Mutex和RWMutex都实现了sync中的lock接口,
3. type Locker interface{
4. 	Lock()
5. 	Unlock()
6. }

自旋锁: 指当一个线程在获取锁的时候,如果锁已经被其他线程获取,那么该线程将循环等待,然后不断地判断锁能否够被成功获取,直到拿到锁才会退出循环。获取锁的线程持续活跃,不挂起(不是通过休眠来使进程阻塞),继续占有cpu

正常模式: 所有goroutine按照FIFO的顺序进行锁获取,被唤醒的goroutine和新请求锁的goroutine同时进行锁获取,通常新请求锁的goroutine更容易获取锁(持续占有cpu),被唤醒的goroutine则不容易获取到锁

饥饿模式: 所有尝试获取锁的goroutine进行等待排队,新请求锁的goroutine不会进行锁获取(禁用自旋),而是加入队列尾部等待获取锁

并发问题测试工具

在编译(compile) 、测试(test) 或者运行(run) Go代码的时候,加上race参数,就有可能发现并发问题。我们可以加上race参数运行,检.测一下是不是有并发问题。如果你go run -race counter.go,就会输出警告信息。
例如:go run -race main.go
在临界资源前加锁,离开临界区的时候释放锁

这里有一-点需要注意: Mutex的零值是还没有goroutine等待的未加锁的状态,所以 你不需要额外的初始化,直接声明变量(如 var mu sync.Mutex)即可。

如果嵌入的struct有多个字段,我们一-般会把Mutex放在要控制的字段上面,然后使用空格把字段分隔开来。即使你不这样做,代码也可以正常编译,只不过,用这种风格去写的话,逻辑会更清晰,也更易于维护。甚至,你还可以把获取锁、释放锁、计数加一的逻辑封装成一个方法, 对外不需要暴露
锁等逻辑:

思考题

如果 Mutex 已经被一个 goroutine 获取了锁,其它等待中的 goroutine 们只能一直等待。那么等这个锁释放后,等待中的goroutine 中哪一个会优先获取 Mutex 呢?

解答:
等待的goroutine们是以FIFO排队的
1)当Mutex处于正常模式时,若此时没有新goroutine与队头goroutine竞争,则队头goroutine获得。若有新goroutine竞争大概率新goroutine获得。
2)当队头goroutine竞争锁失败1ms后,它会将Mutex调整为饥饿模式。进入饥饿模式后,锁的所有权会直接从解锁goroutine移交给队头goroutine,此时新来的goroutine直接放入队尾。
3)当一个goroutine获取锁后,如果发现自己满足下列条件中的任何一个
1.它是队列中最后一个
2.它等待锁的时间少于1ms,则将锁切换回正常模式

新请求锁的goroutine更容易获取锁的原因:
用官方话说就是,新请求锁的 Goroutine具有优势,它正在CPU上执行,而且可能有好几个,所以刚刚唤醒的 Goroutine 有很大可能在锁竞争中失败.

更多可参考大佬文章::Go Mutex 饥饿模式:
另一个大佬总结的:Go_Concurrency学习地址
学习自:极客时间新专栏 《Go并发编程实战课》

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

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

相关文章

Python-大数据分析之常用库

Python-大数据分析之常用库 1. 数据采集与第三方数据接入 1-1. Beautiful Soup ​ Beautiful Soup 是一个用于解析HTML和XML文档的库,非常适用于网页爬虫和数据抓取。可以提取所需信息,无需手动分析网页源代码,简化了从网页中提取数据的过…

【Redis】持久化-RDBAOF混合持久化

文章目录 前置知识RDB(定期备份)触发机制流程说明RDB文件的处理RDB 的优缺点 AOF(实时备份)使用AOF命令写入AOF工作流程文件同步重写机制重写触发机制AOF进制重写流程 混合持久化启动时数据恢复 总结 前置知识 回顾MySQL MySQL的事…

FFmpeg 6.1 开放源码多媒体框架近日发布了重大更新

导读FFmpeg 6.1 开放源码多媒体框架近日发布了重大更新,带来了新功能、新解码器、新过滤器和许多其他变化。 在 FFmpeg 6.0 “Von Neumann “版本发布八个多月后,FFmpeg 6.1 被命名为 “Heaviside”,引入了多线程 Vulkan 硬件加速解码&#x…

Java引用和内部类

引用 引用变量 引用相当于一个 “别名”, 也可以理解成一个指针. 创建一个引用只是相当于创建了一个很小的变量, 这个变量保存了一个整数, 这个整数表示内存中的一个地址. new 出来的数组肯定是在堆上开辟的空间,那么在栈中存放的就是引用,引用存放的的就是一个对象的地址,代表…

Jenkins 配置节点交换内存

查看交换内存 free -hswapon -s创建swap文件 dd if/dev/zero of/mnt/swap bs1M count1024启用交换文件 设置权限 chmod 600 /mnt/swap设置为交换空间 mkswap /mnt/swap启用交换 swapon /mnt/swap设置用户组 chown root:root /mnt/swap查看 swapon -s重启系统也能生效还需要修…

简于外 强于内,联想全新ThinkCentre M90a Pro Gen4以强劲性能开启商

近日,联想发布了最新一代商用台式一体机联想ThinkCentre M90a Pro Gen4。作为联想ThinkCentre M大师系列的旗舰产品,其配备了优质的显示屏,拥有强大的性能和稳定安全的特性,能够满足多样的工作场合,为商用一体机的行业…

前端如何判空

这样判空就会报错 loadNode(node, resolve)console.log("node")console.log(node)if (node.data ! null) {this.get(ctx /publicity/publicityType/typeTreeData?id node.data.id).then((res) > {resolve(res)})}}, 需要这样写,用typeof来做类型判…

格式化名称节点,启动Hadoop

1.循环删除hadoop目录下的tmp文件,记住在hadoop目录下进行 rm tmp -rf 使用上述命令,hadoop目录下为: 2.格式化名称节点 # 格式化名称节点 ./bin/hdfs namenode -format 3.启动所有节点 ./sbin/start-all.sh 效果图: 4.查看节…

Vue中的$nextTick

​🌈个人主页:前端青山 🔥系列专栏:Vue篇 🔖人终将被年少不可得之物困其一生 依旧青山,本期给大家带来vue篇专栏内容:vue中的$nextTick 目录 🐋Vue中的$nextTick有什么作用? 🐋一、…

认知升级:成功需要掌握的思维模型

你好,我是 EarlGrey,一名双语学习者,会一点编程,目前已翻译出版《Python 无师自通》、《Python 并行编程手册》等书籍。 点击上方蓝字关注我,在后台回复“books”,即可领取超值优质电子书合集。 大家好&…

Docker安装Rabbitmq3.12并且prometheus进行监听【亲测可用】

一、安装Rabbitmq 下载镜像: docker pull rabbitmq:3.12-management 安装镜像: docker run -id --restartalways --namerabbitmq -v /usr/local/rabbitmq:/var/lib/rabbitmq -p 15692:15692 -p 15672:15672 -p 5672:5672 -e RABBITMQ_DEFAULT_USERgu…

Go语言多线程爬虫万能模板它来了!

对于长期从事爬虫行业的技术员来说,通过技术手段实现抓取海量数据并且做到可视化处理,我在想如果能写一个万能的爬虫模板,后期遇到类似的工作只要套用模板就能解决大部分的问题,如此提高工作效率何乐而不为? 以下是一个…