Go基础学习07-map注意事项;多协程对map的资源竞争;sync.Mutex避免竟态条件
文章目录
- Go中map使用以及注意事项
- map使用时的并发安全问题
Go中map使用以及注意事项
Go语言中map使用简单示例:
func main() {var mp map[string]int// mp := map[string]int{}val, ok := mp["one"]if ok {fmt.Println(val)} else {fmt.Println(val)}mp["two"] = 10
}
思考一:Go语言的map的键类型为什么不能是函数类型、字典类型、切片类型:
相信学习过其他语言比如Java语言的朋友对于Java中的HashMap都比较熟悉,对于所有键值对元素的数据结构来说,存储过程先计算key的哈希值,随后使用哈希值定位到对应的bucket,将key和value作为元素存储到对应的bucket中。在这个过程中可能会发生哈希碰撞,在Java中对于哈希碰撞常见的解决方案有拉链法,由于哈希碰撞的存在对于哈希表的键的要求,不仅仅能够计算哈希值,同时能够对键进行判等操作(解决哈希碰撞时key重复的问题)。对于Go语言的map的实现仍然如此,需要考虑到哈希碰撞的出现,所以就要求key必须能够进行判等操作。
如果go的map的键为上述三种类型,在运行时就会发生panic。
思考二:Go语言中应该优先考虑那些类型作为map的键的类型
只从性能的角度出发,而不考虑上下文时:在map中比较耗时的操作主要出现在连个地方:
- 把键值转换为哈希值
- 把要查找的键值与哈希桶中的键值做对比
对于所有的基本类型、指针类型,以及数组类型、结构体类型和接口类型,Go 语言都有一套算法与之对应。这套算法中就包含了哈希和判等。
- 以求哈希的操作为例,宽度越小的类型速度通常越快。对于布尔类型、整数类型、浮点数类型、复数类型和指针类型来说都是如此。对于字符串类型,由于它的宽度是不定的,所以要看它的值的具体长度,长度越短求哈希越快。
- 类型的宽度是指它的单个值需要占用的字节数。比如,bool、int8和uint8类型的一个值需要占用的字节数都是1,因此这些类型的宽度就都是1。
- 高级类型如:数组类型的值求哈希实际上是依次求得它的每个元素的哈希值并进行合并,所以速度就取决于它的元素类型以及它的长度。细则同上。
- 结构体类型:哈希实际上就是对它的所有字段值求哈希并进行合并,关键在于它的各个字段的类型以及字段的数量。
优先选用数值类型和指针类型,通常情况下类型的宽度越小越好。如果非要选择字符串类型的话,最好对键值的长度进行额外的约束。
map使用时的并发安全问题
考虑如下代码:
func main() {m := map[int]string{1: "haha",}go read(m)time.Sleep(time.Second)go write(m)time.Sleep(30 * time.Second)fmt.Println(m)
}
func read(m map[int]string) {for {_ = m[1]time.Sleep(1)}
}
func write(m map[int]string) {for {m[1] = "write"time.Sleep(1)}
}
开启两个协程并发对map进行读写操作,上述代码运行直接报如下错误:
goroutine 6 [running]:
main.read(0x0?)/home/wt/Backend/go/goprojects/src/golearndetail/go36/learn09/demo02.go:20 +0x2d
created by main.main/home/wt/Backend/go/goprojects/src/golearndetail/go36/learn09/demo02.go:12 +0xa5goroutine 1 [sleep]:
time.Sleep(0x6fc23ac00)/usr/local/go/src/runtime/time.go:195 +0x135
main.main()/home/wt/Backend/go/goprojects/src/golearndetail/go36/learn09/demo02.go:15 +0xfbgoroutine 7 [sleep]:
time.Sleep(0x1)/usr/local/go/src/runtime/time.go:195 +0x135
main.write(0x0?)/home/wt/Backend/go/goprojects/src/golearndetail/go36/learn09/demo02.go:27 +0x25
created by main.main/home/wt/Backend/go/goprojects/src/golearndetail/go36/learn09/demo02.go:14 +0xecProcess finished with the exit code 2
对于map的读写是非原子性操作,存在资源竞争,不是现成安全的,可以使用如下命令检测:
go run race ...
为了将非并发安全的读取操作更改为并发安全的,可以引入sync.Mutex,在读、写操作前进行加锁操作;操作后进行解锁,保证并发安全。
func main() {m := map[int]string{1: "haha",}var mutex sync.Mutex // 创建一个互斥锁// 启动读协程go read(m, &mutex)// 等待一秒钟,确保读协程已经开始运行time.Sleep(time.Second)// 启动写协程go write(m, &mutex)// 等待足够长的时间,以便读写协程可以运行time.Sleep(30 * time.Second)// 打印最终的mapfmt.Println(m)
}func read(m map[int]string, mutex *sync.Mutex) {for {mutex.Lock() // 在读取之前加锁value := m[1]mutex.Unlock() // 读取完毕后解锁fmt.Println("Read:", value)time.Sleep(1 * time.Second)}
}func write(m map[int]string, mutex *sync.Mutex) {for {mutex.Lock() // 在写入之前加锁m[1] = "write"mutex.Unlock() // 写入完毕后解锁fmt.Println("Write:", m[1])time.Sleep(1 * time.Second)}
}
后续会将sync.Mutex的底层原理进行总结展示。
相关文章:
Go基础学习07-map注意事项;多协程对map的资源竞争;sync.Mutex避免竟态条件
文章目录 Go中map使用以及注意事项map使用时的并发安全问题 Go中map使用以及注意事项 Go语言中map使用简单示例: func main() {var mp map[string]int// mp : map[string]int{}val, ok : mp["one"]if ok {fmt.Println(val)} else {fmt.Println(val)}mp[…...
远程服务器安装anaconda并创建虚拟环境
1、承接上文新用户zrcs,在服务器的zrcs文件夹下直接下载anaconda(很慢): wget https://repo.anaconda.com/archive/Anaconda3-2024.06-1-Linux-x86_64.sh 或者选择本地下载,清华大学开源软件镜像站:https:/…...
什么是IIC通信协议?
IIC(Inter-Integrated Circuit)通信协议,又称为I2C(Inter-Integrated Circuit 2)协议,是一种广泛使用的串行通信协议。它由飞利浦半导体公司(现NXP Semiconductors)开发,…...
P3131 [USACO16JAN] Subsequences Summing to Sevens S Python题解
[USACO16JAN] Subsequences Summing to Sevens S 题目描述 Farmer John’s N N N cows are standing in a row, as they have a tendency to do from time to time. Each cow is labeled with a distinct integer ID number so FJ can tell them apart. FJ would like to ta…...
鸿蒙NEXT开发-ArkUI(基于最新api12稳定版)
注意:博主有个鸿蒙专栏,里面从上到下有关于鸿蒙next的教学文档,大家感兴趣可以学习下 如果大家觉得博主文章写的好的话,可以点下关注,博主会一直更新鸿蒙next相关知识 专栏地址: https://blog.csdn.net/qq_56760790/…...
Matplotlib 使用 LaTeX 渲染图表中的文本、标题和数学公式
Matplotlib 使用 LaTeX 渲染图表中的文本、标题和数学公式 Matplotlib 是一个功能强大的 Python 库,用于绘制各种高质量的图表和图形。在许多科研和技术文档中,数学公式是不可或缺的一部分,LaTeX 提供了精美的数学公式渲染能力。Matplotlib …...
Android 安卓内存安全漏洞数量大幅下降的原因
谷歌决定使用内存安全的编程语言 Rust 向 Android 代码库中写入新代码,尽管旧代码(用 C/C 编写)没有被重写,但内存安全漏洞却大幅减少。 Android 代码库中每年发现的内存安全漏洞数量(来源:谷歌)…...
c++primier第十二章类和动态内存
本章内容包括: 对类成员使用动态内存分配隐式和显式地复制构造函数隐式和显式地重载赋值操作符在构造函数中使用new所必须完成的工作使用静态类成员 将布局new操作符用于对象使用指向对象的指针实现队列抽象数据类型(ADT) 动态内存和类 复习范例和静态类成员 首…...
Ansible学习之ansible-pull命令
想要知道ansible-pull是用来做什么的,就需要了解Ansible的工作模,Ansible的工作模式有两种: push模式 push推送,这是Ansible的默认模式,在主控机上编排好playbook文件,push到远程主机上来执行。pull模式 p…...
Linux:磁盘管理
一、静态分区管理 静态的分区方法不可以动态的增加或减少分区的容量。 1、磁盘分区-fdisk 该命令是用于查看磁盘分区情况,和分区管理的命令 命令格式:fdisk [选项] 设备文件名常用命令: -h:查看分区信息 fdisk系统常用命令&…...
FP7209: 用于紫外线消毒灯的 升压LED恒流驱动芯片
现在社会对于居家消毒也越发重视起来。而居家消毒除了75%浓度酒精及各类消毒液外,利用紫外线灯给衣物表面、房间消毒也是一种很好的选择。FP7209 定位于低压线性恒流驱动,精度高、外围电路简单、使用方便且可靠性高,更可广泛应用于商业照明系…...
【华为HCIP实战课程二】OSPF基础介绍和OSPF RID NBMA配置详解
一、OSPF多区域 自治系统(Autonomous System) 一个自治系统是指使用同一种路由协议交换路由信息的一组路由器 1、Area0为骨干区域 2、ABR--关乎3类LSA后续详解 ABR用来连接骨干区域Area0和非骨干区域,它与骨干区域之间既可以是物理连接,也可以是逻辑上的连接。 3、AS…...
网络编程(13)——单例模式
十三、day13 今天学习如何单例模式实现逻辑层的设计。内容包括服务器如何能捕获信号使其安全退出、单例模标类 1. 什么是单例模式? 单例模式(Singleton),保证一个类仅有一个实例,并提供一个访问它的全局访问点&…...
基于定制开发与2+1链动模式的商城小程序搭建策略
摘要:本文探讨商城小程序的搭建策略,对比自主组建团队和第三方开发两种方式,强调以第三方开发模式为主的优势。阐述在第三方开发模式下,结合定制开发和21链动模式,如何搭建一款有助于企业商业模式创新与智能商业升级的…...
银河麒麟,apt 安装软件报错640Unknown Status
今天把银行麒麟的机器恢复出厂了,然后apt install 安装极其不稳定,故障现象如下图所示: 错误提示里面有: 640 Unknown Status [IP: 106.116.184.122 80] E: 无法下载 http://archive.kylinos.cn/kylin/KYLIN-ALL/pool/universe/f…...
python UNIT 3 选择与循环(2)
目录 1。循环的优化 经典优化分析: 未优化的代码: 细节分析: 优化后的代码: 优化的细节: 性能对比 优化的关键在于: 经典习题讲解:(紫色的解析请重点关注一下) 1。例三 个人代码解析…...
828华为云征文|部署在线文档应用程序 CodeX Docs
828华为云征文|部署在线文档应用程序 CodeX Docs 一、Flexus云服务器X实例介绍二、Flexus云服务器X实例配置2.1 重置密码2.2 服务器连接2.3 安全组配置2.4 Docker 环境搭建 三、Flexus云服务器X实例部署 CodeX Docs3.1 CodeX Docs 介绍3.2 CodeX Docs 部署3.3 CodeX…...
Linux的多线程(线程的创建,退出,取消请求,取消处理例程,线程属性的设置)
进程:是系统分配资源的最小单位,系统会为每一个进程分配一块独立的虚拟内存空间 线程:是系统调度的最小单位,系统不会为线程分配新的内存空间,但是线程也参与系统调度 cpu把时间片分给每一个进程,进程中的时间片再切分分给每一个线程,所以线程也会得到…...
git 本地代码关联远程仓库并推送
初始化代码仓库 如果你的本地项目还没有使用Git管理,首先需要在项目根目录下初始化一个Git仓库 git init添加远程仓库地址 使用 git remote add 命令添加远程仓库 git remote add origin https://github.com/username/repository.git获取远程分支信息 使用 git…...
推荐一个可以把PDF样本册转换为翻页电子书的网站
随着互联网的普及,越来越多的企业和个人开始意识到线上展览的重要性。如何将实体样本册转化为线上版本,让更多人了解和欣赏自己的产品与服务? 一、网站简介 这款PDF样本册免费上传网站名为“FLBOOK”,致力于为广大用户提供便捷…...
【Linux 23】线程池
文章目录 🌈 一、线程池的概念🌈 二、线程池的应用场景🌈 三、线程池的实现 🌈 一、线程池的概念 线程池 (thread pool) 是一种利用池化技术的线程使用模式。 虽然创建线程的代价比创建进程的要小很多,但小并不意味着…...
Rust SQLite 跨平台使用
引言 Rust因其内存安全性和高性能受到越来越多开发者的青睐。在许多项目中,SQLite作为一种轻量级的嵌入式数据库,与Rust的结合为跨平台应用程序提供了强大的支持。本文将详细探讨Rust如何实现跨平台功能,如何在不同平台上使用Rust库…...
docker运行arm64架构的镜像、不同平台镜像构建
背景 Docker 允许开发者将应用及其依赖打包成一个轻量级、可移植的容器,实现“一次构建,到处运行”的目标。然而,不同的操作系统和硬件架构对容器镜像有不同的要求。例如,Linux 和 Windows 系统有不同的文件系统和系统调用&#…...
vue基于Spring Boot框架的高校实验室预约管理系统
目录 毕设制作流程功能和技术介绍系统实现截图开发核心技术介绍:使用说明开发步骤编译运行代码执行流程核心代码部分展示可行性分析软件测试详细视频演示源码获取 毕设制作流程 (1)与指导老师确定系统主要功能; (2&am…...
Linux中find命令详解
记录linux中find命令的详细用法。 文章目录 find命令简介基本语法常用选项-name-iname-type-size-mtime,-atime,-ctime-perm-user-group-delete-exec-printand or find --help find命令简介 find 是一个搜索目录树以查找一个文件或一组文件的程序。它遍历目录树并报告与用户规…...
无水印短视频素材下载网站有哪些?十个高清无水印视频素材网站分享
你知道怎么下载无水印视频素材吗?今天小编就给大家推荐十个高清无水印视频素材下载的网站,如果你也是苦于下载高清无水印的短视频素材,赶紧来看看吧~ 1. 稻虎网 首推的是稻虎网。这个网站简直就是短视频创作者的宝库。无论你需要…...
SpringBoot+Activiti7工作流入门实例
目录 文章目录 目录准备Activiti建模工具1、BPMN-js在线设计器1.1 安装1.2 使用说明1.3运行截图2、IDEA安装Activiti Designer插件2.1安装插件2.2 设置编码格式防止中文乱码2.3 截图简单工作流入门实例1. 新建Spring Boot工程2. 引入Activiti相关依赖添加版本属性指定仓库添加依…...
Azure OpenAI检索增强微调:使用 GPT-4o 对 GPT-4o mini 进行微调,以适应特定领域的应用
定制是关键! 生成式人工智能对企业最有影响力的应用之一是创建自然语言界面,这些界面经过定制,可以使用特定领域和用例数据来提供更好、更准确的响应。这意味着回答有关特定领域的问题,例如银行、法律和医疗领域。 我们经常谈…...
ISP Pipeline
系列文章目录 文章目录 系列文章目录前言一、RAW域二、RGB域三、YUV域总结 前言 一、RAW域 黑电平校正(BLC)数字增益调整(DGain)自动白平衡(AWB)局部色调映射(LTM)坏点修复…...
< IDE编程环境配置>
IDE编程环境配置 LIB,DLL区别 我们在写项目时会链接(调用)第3方库,或者比如在vs的解决方案solution创建项目project时,不仅可以开发可执行程序exe(可单独运行)(windows/控制台 应用…...
医院网站建设公司价格/我赢seo
Serializable是序列化的意思,表示将一个对象转换成可存储或可传输的状态。序列化后的对象可以在网络上进行传输,也可以存储到本地.序列化的方法很简单,实现Serializable接口就可以了. 1.比如有个Person类 public class Person implements Serializable{ private S…...
wordpress post攻击/营销策划公司介绍
Pythen基础知识1.py简介:Py语言是由代码转换成c字节码然后再转换成机器码编码类型:ascll、万国码、utf-8、gbk(汉字)2.py基础知识2.1py变量变量命名:通俗易懂用一定含义的变量命名字母、数字、下划线命名,不…...
找网站建设企业/西安seo服务公司排名
您不需要集成任何内容。您可以使用pygame屏幕作为GUI。公平警告:它没有内置功能,如按钮或弹出窗口。每次都需要硬编码。通过集成,如果你的意思是python代码的结果应该显示在屏幕上,那么这将发生。如果要将另一个pytho…...
wordpress房地产插件/教育培训机构有哪些
2019独角兽企业重金招聘Python工程师标准>>> 在开始菜单中找到vmware 安装文件夹点击虚拟网络编辑器;查看子网掩码和网关地址,选中vmnet8,点击nat设置 。获取子网掩码255.255.255.0,网关192.168.199.2点击dhcp设置,获取…...
电子产品东莞网站建设/天津seo网络
由于一些嵌套特别深的数据,导致数据更新了。UI没有更新(连深度监听都没有监听到),我捉摸着有没有和react一样的立即更新UI的API呢 this.forceUpdate()呢?结果还真有: this.$forceUpdate(); 转载于:https://…...
连云港seo/南京 seo 价格
ConstraintLayout的普及让Android的开发者们能更方便地进行布局,但如何在代码中设置ConstraintLayout的约束呢?网上的资料不太详细,在这里归纳总结一下。ConstraintSet这个类在官方文档上是这样描述的:This class allows you to d…...