go数据类型-sync.map

这篇具有很好参考价值的文章主要介绍了go数据类型-sync.map。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

定义

在runtime的sync.map包中有定义:

type Map struct {
	mu Mutex // 锁
	read atomic.Pointer[readOnly] //包含了readOnly类型的一个struct,下方把 Pointer 也贴了
	dirty map[any]*entry	 // 一个map 存储数据
	misses int          // 错过、没有命中
}

// readOnly is an immutable struct stored atomically in the Map.read field.
type readOnly struct {
	m       map[any]*entry // 一个map,这个map是 read持有的
	amended bool // true if the dirty map contains some key not in m.
    // 追加,这里已经注释了 当dirty 的map中的key 不在 m的map中(就是 read的)就显示为 true
}

// go 的泛型
type Pointer[T any] struct {
	_ [0]*T
	_ noCopy
	v unsafe.Pointer
}
go数据类型-sync.map

整体的结构就如上图。

sync.map中有两个map 都是通过指针的形式 ,指向同一份value,但是key两个map都有各自存储。

分析原理

看究竟是如何解决map并发的问题的。

正常读写

go数据类型-sync.map

正常读写走 m,就是read那个通过泛型结构体指向的那个 map,通过m这个map进行查找后,读取或者更改。

这个时候 misses = 0 ,amended=false

追加

go数据类型-sync.map

如何写一个key,发现m中没有,那么需要去dirty中追加。

开始追加前,需要对dirty进行上锁,写完解锁

如图现在追加了一个 d,这个时候 m中没有这个d的信息。

这个时候 misses = 0 ,amended=true 这个时候有了 dirty的key 不在m中了。

追加后读写

go数据类型-sync.map

这时候就会出现 找d时候,发现m中没有并 amended=true ,就会去 dirty中找,而且每找一次,都会给 misses 加1

这个时候 misses = 1 ,amended=true 

dirty 提升

misses 等于 len(dirty) 就会触发dirty提升,替代m。

go数据类型-sync.map

当再次出现追加的情况,重塑 dirty

go数据类型-sync.map
这时候把  misses = 0 ,amended=false 复原

删除

删除比较麻烦,分为正常删除,和在上面的各种状态下进行删除。

正常删除

go数据类型-sync.map

只需要把pointer置为nil就好,value因为没有对象指向它,在垃圾回收时候,会被标记为白色,被清理。

追加后删除

go数据类型-sync.map

正常也是置为nil

删除后,提升

go数据类型-sync.map

提升之后,如果重建 dirty,就不会重建这个d

这里d标记为 expunge 是为了告诉下方,
这个key已经被删除了,不用同步了,如果出现删除d的请求,不需要和下方dirty同步了。
而且当再对D进行追加时候,这时候 m中有d,但是,应该要放到dirty中去完成。

总结:

1. map 在扩容时会有并发问题

2.sync.Map 使用了两个map,分离了扩容问题

3.不会引发扩容的操作(查、改)使用read map

4.可能引发扩容的操作(新增)使用 dirty map

5.不是采用读写分离的办法文章来源地址https://www.toymoban.com/news/detail-747823.html

到了这里,关于go数据类型-sync.map的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • <C++>map 容器快速上手|自定义数据类型排序的避坑理解

    ✅作者简介:热爱后端语言的大学生,CSDN内容合伙人 ✨精品专栏:C++面向对象 🔥系列专栏:C++泛型编程 🔥前言 继 set 容器后,今天总结一下 map 容器的功能,从零到一快速掌握基本使用与常用接口。 map 在 STL 编程中与 vector 、 list 、 set 具有同等重要的地位,键值对的方式

    2024年02月02日
    浏览(40)
  • 深入探讨 Go 语言中的 Map 类型

    Go 语言中的 map 类型是一种非常强大且常用的数据结构,它提供了一种键值对的映射关系。本篇博客将深入讨论 Go 中的 map 类型,包括其基本用法、特性、以及一些最佳实践。 1. 声明和初始化 在 Go 中,你可以使用 make 函数来创建一个空的 map 。 map 的键和值可以是任意数据类

    2024年01月17日
    浏览(42)
  • OpenCV中有许多常用的数据类型

    OpenCV中有许多常用的数据类型,以下是其中一些常见的数据类型: cv::Mat:用于表示图像和矩阵的类。 cv::Point:用于表示二维平面上的点,包含 x 和 y 坐标。 cv::Rect:用于表示矩形区域,包含左上角的点和矩形的宽度和高度。 cv::Size:用于表示尺寸,包含宽度和高度。 cv::S

    2024年01月19日
    浏览(33)
  • 包含引用类型字段的自定义结构体,能作为map的key吗

    在 Go 语言中, map 是一种内置的数据类型,它提供了一种高效的方式来存储和检索数据。 map 是一种无序的键值对集合,其中每个键与一个值相关联。使用 map 数据结构可以快速地根据键找到对应的值,而无需遍历整个集合。 在 Go 语言中, map 是一种内置的数据类型,可以通

    2024年02月07日
    浏览(39)
  • golang--sync.map(安全字典)

    引言:在Go语言中,多个goroutine之间安全地共享数据是一项挑战。为了解决这个问题,Go语言提供了sync包,并在其中引入了sync.Map类型。sync.Map是一种并发安全的映射数据结构,它提供了高效的并发访问方式,避免了显式的锁操作。本文将深入探讨sync.Map的使用方法和底层实现

    2024年02月13日
    浏览(46)
  • 一文了解io包中的discard类型

    io.discard 是Go语言标准库提供一个结构体类型,其在丢弃不需要的数据场景下非常好用。本文我们将从 io.discard 类型的基本定义出发,讲述其基本使用和实现原理,接着简单描述 io.discard 的使用场景,基于此完成对 io.discard 类型的介绍。 io.discard 是 Go语言提供的一个 Writer ,这

    2024年02月15日
    浏览(39)
  • 【Go 基础篇】Go语言结构体详解:打开自定义类型的大门

    嗨,Go语言学习者们!在编程的世界里,数据是核心,而结构体(Struct)是一种能够帮助我们更有组织地存储和操作数据的重要工具。在本篇博客中,我们将深入探讨Go语言中结构体的概念、定义、初始化、嵌套、方法以及与面向对象编程的关系,带你逐步领略结构体的魅力。

    2024年02月10日
    浏览(45)
  • 35 | 并发安全字典sync.Map (下)

    我们在上一篇文章中谈到了,由于并发安全字典提供的方法涉及的键和值的类型都是interface{ },所以我们在调用这些方法的时候,往往还需要对键和值的实际类型进行检查。 这里大致有两个方案。我们上一篇文章中提到了第一种方案,在编码时就完全确定键和值的类型,然后

    2024年01月24日
    浏览(35)
  • Golang 线程安全与 sync.Map

    前言 线程安全通常是指在并发环境下,共享资源的访问被适当地管理,以防止竞争条件(race conditions)导致的数据不一致 Go语言中的线程安全可以通过多种方式实现 实现方式 互斥锁(Mutexes) Go的sync包提供了Mutex和RWMutex类型来确保在一个时间点只有一个协程可以访问某个资

    2024年01月24日
    浏览(39)
  • Golang实践:用Sync.Map实现简易内存缓存系统

    定义了一个Cache结构体,其中使用sync.Map作为底层数据结构来存储缓存项。Set方法用于设置缓存项,指定键、值以及过期时间。Get方法用于获取缓存项,如果缓存项存在且未过期,则返回值和true,否则返回nil和false。方法的接受者为指针类型,是为了对Cache对象进行操作,并在

    2024年04月15日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包