【Golang】Golang的Map的线程安全问题
文章目录
- 前言
- 一、场景介绍
- 二、线程安全的Map的使用
- 四、总结
前言
在 Golang 编程中,map 是一种常用的数据结构,用于存储键值对。然而,Golang 的 map 在并发访问时是线程不安全的。如果多个 goroutine 同时读写同一个 map,可能会导致数据竞争和程序崩溃。本文将详细介绍 Golang 中 map 的线程不安全性,并提供一些解决方案,帮助开发者在并发编程中正确使用 map。
一、场景介绍
1. 什么是线程不安全
线程不安全是指在多线程(或多 goroutine)环境下,多个线程同时访问和修改共享数据时,可能会导致数据不一致或程序崩溃。对于 Golang 的 map 来说,如果没有适当的同步机制,多个 goroutine 同时读写同一个 map 就会出现这种情况。
2. map 是线程不安全的
在同一时间点,两个 goroutine 对同一个 map 进行读写操作是不安全的。举个例子:
某 map 桶数量为 4,即 B=2。此时 goroutine1 来插入 key1,goroutine2 来读取 key2。可能会发生如下过程:
- 1.goroutine2 计算 key2 的 hash 值,B=2,并确定桶号为 1。
- 2.goroutine1 添加 key1,触发扩容条件。
- 3.B=B+1=3,buckets 数据迁移到 oldbuckets。
- 4.goroutine2 从桶 1 中遍历,获取数据失败。
3. 线程不安全的示例
以下是一个简单的示例,展示了在没有同步机制的情况下,多个 goroutine 同时读写 map 可能导致的错误:
package mainimport ("fmt""sync"
)func main() {m := make(map[int]int)var wg sync.WaitGroupfor i := 0; i < 10; i++ {wg.Add(1)go func(i int) {defer wg.Done()m[i] = i}(i)}wg.Wait()fmt.Println(m)
}
二、线程安全的Map的使用
1. 使用 sync.Mutex 进行同步
为了避免数据竞争,可以使用 sync.Mutex 进行同步。sync.Mutex 提供了锁机制,确保同一时刻只有一个 goroutine 可以访问 map。
示例:
package mainimport ("fmt""sync"
)func main() {m := make(map[int]int)var mu sync.Mutexvar wg sync.WaitGroupfor i := 0; i < 10; i++ {wg.Add(1)go func(i int) {defer wg.Done()mu.Lock()m[i] = imu.Unlock()}(i)}wg.Wait()fmt.Println(m)
}
在这个示例中,使用 mu.Lock() 和 mu.Unlock() 确保每次只有一个 goroutine 可以访问 map,从而避免数据竞争。
2. 使用 sync.RWMutex 进行读写锁
如果读操作远多于写操作,可以使用 sync.RWMutex 进行读写锁。sync.RWMutex 提供了读锁和写锁,允许多个 goroutine 同时进行读操作,但写操作仍然是互斥的。
示例:
package mainimport ("fmt""sync"
)func main() {m := make(map[int]int)var mu sync.RWMutexvar wg sync.WaitGroupfor i := 0; i < 10; i++ {wg.Add(1)go func(i int) {defer wg.Done()mu.Lock()m[i] = imu.Unlock()}(i)}for i := 0; i < 10; i++ {wg.Add(1)go func(i int) {defer wg.Done()mu.RLock()fmt.Println(m[i])mu.RUnlock()}(i)}wg.Wait()
}
在这个示例中,使用 mu.RLock() 和 mu.RUnlock() 进行读操作,使用 mu.Lock() 和 mu.Unlock() 进行写操作,从而提高并发读的效率。
3. 使用 sync.Map
Golang 标准库提供了 sync.Map,它是一个并发安全的 map 实现,适用于需要高并发访问的场景。sync.Map 提供了原子操作,避免了手动加锁的复杂性。
示例:
package mainimport ("fmt""sync"
)func main() {var m sync.Mapvar wg sync.WaitGroupfor i := 0; i < 10; i++ {wg.Add(1)go func(i int) {defer wg.Done()m.Store(i, i)}(i)}for i := 0; i < 10; i++ {wg.Add(1)go func(i int) {defer wg.Done()value, _ := m.Load(i)fmt.Println(value)}(i)}wg.Wait()
}
在这个示例中,使用 m.Store() 进行写操作,使用 m.Load() 进行读操作,sync.Map 内部已经实现了并发安全。
四、总结
Golang 中的 map 在并发访问时是线程不安全的,如果不加以同步处理,可能会导致数据竞争和程序崩溃。本文介绍了几种解决方案,包括使用 sync.Mutex、sync.RWMutex 和 sync.Map。希望通过本文的介绍,读者能够更好地理解 Golang 中 map 的线程不安全性,并在实际项目中正确使用 map 进行并发编程。
相关文章:
【Golang】Golang的Map的线程安全问题
文章目录 前言一、场景介绍二、线程安全的Map的使用四、总结 前言 在 Golang 编程中,map 是一种常用的数据结构,用于存储键值对。然而,Golang 的 map 在并发访问时是线程不安全的。如果多个 goroutine 同时读写同一个 map,可能会…...
指向指针的指针+ 值传递的理解
//17、下面的程序会出现什么结果 #include #include void getmemory(char *p) { p(char *) malloc(100); strcpy(p,”hello world”); } int main( ) { char *strNULL; getmemory(str); printf(“%s/n”,str); free(str); return 0; } // 程序崩溃,…...
CSS常用定位
一、relative 相对原先的位置进行定位 {position: relative;left: 50px; /* 相对原先位置左边的距离 */top: 100px; /* 相对原先位置上边的距离 */ } 二、absolute 绝对定位,是相对于最近有定位的父级元素进行定位 {position: absolute;righ…...
【Linux】从零开始使用多路转接IO --- select
碌碌无为,则余生太长; 欲有所为,则人生苦短。 --- 中岛敦 《山月记》--- 从零开始认识五种IO模型 1 前言2 认识多路转接select3 多路转接select等待连接4 完善代码5 总结 1 前言 上一篇文章我们讲解了五种IO模型的基本概念,并…...
ArcGIS Pro SDK (二十一)渲染
ArcGIS Pro SDK (二十一)渲染 文章目录 ArcGIS Pro SDK (二十一)渲染1 定义唯一值呈现器定义2 为最新观测值设置唯一值渲染器3 为先前的观测值设置唯一值渲染器4 设置简单的渲染器以绘制轨迹线5 检查先前的观测值和轨道线可见性6 使轨迹线和先前的观测点可见7 检索当前观测…...
FPGA在物联网边缘计算中的应用!!!
FPGA(现场可编程门阵列)在物联网边缘计算中的应用正变得越来越重要。边缘计算是一种分布式计算架构,它将数据的处理分散到网络的边缘,靠近数据源,而不是集中在数据中心处理。以下是FPGA在物联网边缘计算中的几个关键应…...
【解决】Linux环境中mysqlclient安装失败问题
问题描述 在Linux系统下安装myslclient报异常。系统为Centos 8 使用 pip install mysqlclient 报出下面的异常 error: subprocess-exited-with-error Getting requirements to build wheel did not run successfully.│ exit code: 1╰─> [30 lines of output]/bin/sh: pkg…...
✨ Midjourney中文版:创意启航,绘梦无界 ✨
Midjourney AI超强绘画 (原生态系统)用户端:Ai Loadinghttps://www.mjdiscord.com 项目详细介绍飞书文档:Docshttps://ivqklkndl4k.feishu.cn/docx/GRnMdCbcooWkwTx1RU4cZjGVnzb?fromfrom_copylk 🌐 无缝体验,中文定制…...
软件(1)
软件 常考软件 图像软件 Flash 一款二维动画处理软件 photoshop 图像处理界的“巨无霸” ACDSee ACDSee是常用的图片管理编辑软件,尽管也可以支持WAV格式的音频播放, 但目前主要是作为看图软件 音频软件 Winamp Winamp是数字媒体播放的先驱Audition Audi…...
linux perf 环境部署和基本测试(基于Ubuntu20.04)
1,linux 安装perf sudo apt-ge install linux-tools-common sudo apt-get install linux-tools-$(uname -r) linux-tools-generic -y 2 补充安装 sudo apt-get install python3-q-text-as-data 3,perf常用命令 larkubuntu:~$ perf usage: perf [--version] [--hel…...
【网络面试篇】HTTP(1)(笔记)——状态码、字段、GET、POST、缓存
目录 一、相关问题 1. HTTP请求常见的状态码和字段? (1)状态码 (2)字段 ① Host 字段 ② Content-length 字段 ③ Connection 字段 ④ Content-Type 字段 ⑤ Content-Encoding 字段 2. GET 和 POST 的区别&a…...
HTML 基础标签——分组标签 <div>、<span> 和基础语义容器
文章目录 1. `<div>` 标签特点用途示例2. `<span>` 标签特点用途示例3. `<fieldset>` 标签特点用途示例4. `<section>` 标签特点用途示例5. `<article>` 标签特点用途示例总结HTML中的分组(容器)标签用于结构化内容,将页面元素组织成逻辑区域…...
SS928V100 ISP常见问题列表
下载链接: https://download.csdn.net/download/quantum7/89948226 1 FAQ 1 1.1 ISP 1 1.1.1 如何解决整体锐度不足 1 1.1.2 如何解决图像发蒙问题,提高通透性 2 1.1.3 如何解决低照度清晰度差 2 1.1.4 如何解决图像清晰度与物体边缘白边和黑边问题…...
AI写诗:自动版大唐宫体诗
大唐学子,手拿一本小卷(类书),从中挑选过去他们(权威)认为好的词来拼接一首诗,此类诗词称作“宫体诗”,在初唐时期甚是流行。 写“宫体诗”的过程有木有那么一丝丝的熟悉?…...
Java复习31(PTA)
sdust-Java-字符串集合求并集 分数 15 全屏浏览 切换布局 作者 张峰 单位 山东科技大学 从键盘接收N个英文字符串(其中不同的字符串数量大于10),从头开始取5个不同的字符串放入一个集合S1,然后接着取5个不同的字符串放入另一个…...
【Linux系列】Linux 系统中的软连接管理
💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...
@layer(级联层)
在css样式表(文件)中声明layer为样式添加级联层,其意义在于可以使用它重新定义样式的叠层关系. layer后声明的级联层里面的样式将覆盖前声明的级联层里面的相同属性.在级联层外声明的样式会覆盖级联层里面的相同属性样式,同一层级里面的样式冲突,依然按照优先级来计算. 在级联层…...
nginx代理websocket服务
一、nginx代理websocket服务 一)nginx代理ws服务 在nginx中,可以通过proxy_pass指令来代理WebSocket服务。 以下是一个示例配置: map $http_upgrade $connection_upgrade {default upgrade; close; }upstream ws_backend {server 127.0.0.1:…...
第二十七章 Vue异步更新之$nextTick
目录 一、概述 二、完整代码 2.1. main.js 2.2. App.vue 一、概述 需求:编辑标题, 弹出显示编辑框自动聚焦 1. 点击编辑,显示编辑框 2. 让编辑框,立刻获取焦点 我们常规的思路可能会编写如下代码来实现: 问题:…...
【51 Pandas+Pyecharts | 深圳市共享单车数据分析可视化】
文章目录 🏳️🌈 1. 导入模块🏳️🌈 2. Pandas数据处理2.1 读取数据2.2 查看数据信息2.3 处理起始时间、结束时间2.4 增加骑行时长区间列2.5 增加骑行里程区间列 🏳️🌈 3. Pyecharts数据可视化3.1 各…...
【kafka】Golang实现分布式Masscan任务调度系统
要求: 输出两个程序,一个命令行程序(命令行参数用flag)和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽,然后将消息推送到kafka里面。 服务端程序: 从kafka消费者接收…...
shell脚本--常见案例
1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件: 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...
汽车生产虚拟实训中的技能提升与生产优化
在制造业蓬勃发展的大背景下,虚拟教学实训宛如一颗璀璨的新星,正发挥着不可或缺且日益凸显的关键作用,源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例,汽车生产线上各类…...
定时器任务——若依源码分析
分析util包下面的工具类schedule utils: ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类,封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz,先构建任务的 JobD…...
大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计
随着大语言模型(LLM)参数规模的增长,推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长,而KV缓存的内存消耗可能高达数十GB(例如Llama2-7B处理100K token时需50GB内存&a…...
rnn判断string中第一次出现a的下标
# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...
sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!
简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求,并检查收到的响应。它以以下模式之一…...
处理vxe-table 表尾数据是单独一个接口,表格tableData数据更新后,需要点击两下,表尾才是正确的
修改bug思路: 分别把 tabledata 和 表尾相关数据 console.log() 发现 更新数据先后顺序不对 settimeout延迟查询表格接口 ——测试可行 升级↑:async await 等接口返回后再开始下一个接口查询 ________________________________________________________…...
FFmpeg:Windows系统小白安装及其使用
一、安装 1.访问官网 Download FFmpeg 2.点击版本目录 3.选择版本点击安装 注意这里选择的是【release buids】,注意左上角标题 例如我安装在目录 F:\FFmpeg 4.解压 5.添加环境变量 把你解压后的bin目录(即exe所在文件夹)加入系统变量…...
「全栈技术解析」推客小程序系统开发:从架构设计到裂变增长的完整解决方案
在移动互联网营销竞争白热化的当下,推客小程序系统凭借其裂变传播、精准营销等特性,成为企业抢占市场的利器。本文将深度解析推客小程序系统开发的核心技术与实现路径,助力开发者打造具有市场竞争力的营销工具。 一、系统核心功能架构&…...
