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

邳州网站开发中国企业培训网

邳州网站开发,中国企业培训网,深圳网站制作首荐祥奔科技,ydblog wordpress为什么 Go 语言在多个 goroutine 同时访问和修改同一个 map 时,会报出 fatal 错误而不是 panic?我们该如何应对 map 的数据竞争问题呢? 这篇文章将带你一步步了解背后的原理,并引出解决 map 并发问题的方案。 Map 数据竞争 首先…

请添加图片描述

为什么 Go 语言在多个 goroutine 同时访问和修改同一个 map 时,会报出 fatal 错误而不是 panic?我们该如何应对 map 的数据竞争问题呢?

这篇文章将带你一步步了解背后的原理,并引出解决 map 并发问题的方案。

Map 数据竞争

首先,什么是 Map 数据竞争。

当两个或多个 goroutine 在没有适当同步机制的情况下,同时访问同一块数据,且至少有一个 goroutine 在修改这块数据,就会发生数据竞争。这种情况可能导致程序的行为异常,甚至崩溃。

而 map 是 Go 中的一种常用的数据结构,提供了快速的 Key/Value 存储能力。但 Go 默认的 map 并不提供并发安全。这意味着,如果我们没有采取措施来控制 map 同步访问,如果多个 goroutine 同时对一个map进行读写操作,就可能会引发数据竞争。

Map 数据竞争产生 fatal error

在 Go 语言中,处理错误的方式通常是通过返回 Error 或者 panic。然而一旦程序检测到 map 的数据竞争,就会抛出 fatal 错误。而 fatal error 即意味会立刻崩溃。毫无疑问,Go 选择了更严格的处理方式。

通过一个简单的例子演示 fatal 错误是如何被触发的:

package mainimport ("sync"
)func main() {m := make(map[int]int)wg := sync.WaitGroup{}for i := 0; i < 10; i++ {wg.Add(1)go func() {defer wg.Done()for j := 0; j < 1000; j++ {m[j] = j}}()}wg.Wait()
}

这个例子中,我创建了一个map 类型变量 m,然后启动了10个 goroutine,每个 goroutine 都尝试向map中写入 1000 个键值对。由于 map 在 Go 中不是并发安全的,这将导致数据竞争。

这个代码可能会触发如下的 fatal 错误,输出如下所示:

fatal error: concurrent map writesgoroutine 6 [running]:... 省略exit status 2

为什么 fatal 错误, 而非 panic?

fatal 错误让我们没有在程序运行时进行补救。我猜测这背后的原因主要是以下两点:

请添加图片描述

立即暴露问题

这种处理方式确保了一旦发生数据竞争,程序将立即停止运行,迫使我们直面问题,不能逃避。

这不仅有利于我们快速发现解决并发 bug,也促使我们编写代码时,应更注重并发安全,避免发生这类问题。

虽然,这种方式可能会导致程序在运行时突然停止,但长远来看,它有助于提高程序的健壮性和可靠性。

防止数据腐败

数据竞争的后果可能非常严重,尤其是在复杂的并发系统中。

当多个goroutine不协调地访问和修改同一个map时,可能会导致map的内部状态变得不一致,甚至损坏。

这种状态的不确定性不仅会导致程序行为异常,还可能导致难以追踪的bug。

深入源码:map 并发检测

当 Go 检测到 map 的并发写入,会通过 throw 函数抛出 fatal 错误。这一过程发生在 mapassign 函数中。

以下是简化后的 mapassign 函数的伪代码,:

func mapassign(t *maptype, h *hmap, key unsafe.Pointer) unsafe.Pointer {// 检查是否有其他goroutine正在写入mapif h.flags&hashWriting != 0 {throw("concurrent map writes")}// ...其他map赋值逻辑...// 设置标志位,表示有goroutine正在写入maph.flags |= hashWriting// ...执行map的赋值逻辑...// 写入完成,清除写入标志位h.flags &^= hashWritingreturn val
}

通过这段代码,就能理解 fatal 错误是如何被触发的。对,重点就是 h.flags&hashWriting 这段条件判断。

如何避免数据竞争

在 Go 中,最常用的并发控制机制是使用 channel 或 sync 包中的工具。另外,Go 还提供了一个并发安全的 map 类型 - sync.Map。

sync.Mutex

我将通过以下这段代码演示如何使用 sync.Mutex 避免数据竞争:

package mainimport ("sync"
)func main() {m := make(map[int]int)var mu sync.Mutexwg := sync.WaitGroup{}for i := 0; i < 10; i++ {wg.Add(1)go func() {defer wg.Done()for j := 0; j < 1000; j++ {mu.Lock()m[j] = jmu.Unlock()}}()}wg.Wait()
}

在这个例子中,我们使用了 sync.Mutex 确保每次只有一个 goroutine 可以写入 map,从而避免数据竞争,保证程序的稳定性和正确性。

sync.Map

虽然 Go 的标准 map 非并发安全,但 Go 在 1.9 版本中引入了一个并发安全的 map 类型 - sync.Map,专门设计来处理并发场景下的 Key/Value 存储。

sync.Map 有一些特别的特性,它不需要显式的锁操作来保证并发安全,为它内部已经处理好了同步机制,这可简化我们的并发编程。

以下示例使用 sync.Map 改写了之前通过 sync.Mutex 实现的代码。

package mainimport ("sync""fmt"
)func main() {var sm sync.Mapwg := sync.WaitGroup{}// 写入数据for i := 0; i < 10; i++ {wg.Add(1)go func(n int) {defer wg.Done()sm.Store(n, n*n)}(i)}// 读取数据for i := 0; i < 10; i++ {wg.Add(1)go func(n int) {defer wg.Done()if value, ok := sm.Load(n); ok {fmt.Printf("Key: %v, Value: %v\n", n, value)}}(i)}wg.Wait()
}

这个例子中,sync.Map 的 Store 方法用于存储 Key/Value,Load 方法用于读取数据。我们通过这种方式就可以在多个 goroutine 中安全地使用map,而不必担心数据竞争。

另外,sync.Map 相对于传统的 sync.Mutext + map 的组合,除简化了并发编程,它还针对并发场景做了一些优化,如无锁读、细粒度锁机制(非锁整个 Map)等等。更多细节,可自行研究。

总结

在本文中,我们探讨了 Go 语言处理 map 并发操作数据竞争情况下的处理方式。这种设计突显了 Go 对并发安全的重视。另外,通过 Go 提供的 sync.Mutex 和sync.Map 等工具,可有效避免数据竞争,确保我们构建出稳定和高效的并发应用。

我想说,对这些机制的理解对于我们编写出健壮的Go程序是至关重要的。

博文地址:从 fatal 错误到 sync.Map:Go中 Map 的并发策略


文章转载自:
http://demandable.mkbc.cn
http://hma.mkbc.cn
http://dissolute.mkbc.cn
http://winter.mkbc.cn
http://helicon.mkbc.cn
http://foreclosure.mkbc.cn
http://ial.mkbc.cn
http://sublapsarian.mkbc.cn
http://spiegeleisen.mkbc.cn
http://narcomatous.mkbc.cn
http://panne.mkbc.cn
http://zero.mkbc.cn
http://sixpenny.mkbc.cn
http://sncf.mkbc.cn
http://unnational.mkbc.cn
http://copyreader.mkbc.cn
http://fluviomarine.mkbc.cn
http://nurture.mkbc.cn
http://rubus.mkbc.cn
http://tetramethyl.mkbc.cn
http://ornithoid.mkbc.cn
http://unnotched.mkbc.cn
http://honkey.mkbc.cn
http://indissoluble.mkbc.cn
http://tropine.mkbc.cn
http://monocephalous.mkbc.cn
http://vannetais.mkbc.cn
http://berber.mkbc.cn
http://jellyfish.mkbc.cn
http://capitulary.mkbc.cn
http://escaut.mkbc.cn
http://hempy.mkbc.cn
http://unscholarly.mkbc.cn
http://ectoblast.mkbc.cn
http://gunnar.mkbc.cn
http://folliculin.mkbc.cn
http://portraitist.mkbc.cn
http://pesto.mkbc.cn
http://endymion.mkbc.cn
http://shamal.mkbc.cn
http://prepuce.mkbc.cn
http://cossette.mkbc.cn
http://computer.mkbc.cn
http://berascal.mkbc.cn
http://limmer.mkbc.cn
http://gelatinoid.mkbc.cn
http://judoka.mkbc.cn
http://zagreus.mkbc.cn
http://prebend.mkbc.cn
http://further.mkbc.cn
http://monophthong.mkbc.cn
http://helio.mkbc.cn
http://foraminifera.mkbc.cn
http://popish.mkbc.cn
http://kayser.mkbc.cn
http://pyrogen.mkbc.cn
http://heatedly.mkbc.cn
http://hungerly.mkbc.cn
http://pleb.mkbc.cn
http://jade.mkbc.cn
http://cruellie.mkbc.cn
http://extraparental.mkbc.cn
http://petrologist.mkbc.cn
http://retaliatory.mkbc.cn
http://erubescence.mkbc.cn
http://sugi.mkbc.cn
http://fruitfully.mkbc.cn
http://helianthine.mkbc.cn
http://panoply.mkbc.cn
http://tzar.mkbc.cn
http://cartomancy.mkbc.cn
http://quaint.mkbc.cn
http://thyroglobulin.mkbc.cn
http://cognizance.mkbc.cn
http://furbelow.mkbc.cn
http://baksheesh.mkbc.cn
http://snowswept.mkbc.cn
http://tricyclist.mkbc.cn
http://excuria.mkbc.cn
http://devel.mkbc.cn
http://nif.mkbc.cn
http://gerundgrinder.mkbc.cn
http://posset.mkbc.cn
http://hydronics.mkbc.cn
http://rubbedy.mkbc.cn
http://orientalist.mkbc.cn
http://daa.mkbc.cn
http://worktable.mkbc.cn
http://gcse.mkbc.cn
http://temperance.mkbc.cn
http://nitroaniline.mkbc.cn
http://misspeak.mkbc.cn
http://spermatogenesis.mkbc.cn
http://columbine.mkbc.cn
http://salary.mkbc.cn
http://sacculate.mkbc.cn
http://ataraxic.mkbc.cn
http://dialectical.mkbc.cn
http://athwartships.mkbc.cn
http://emr.mkbc.cn
http://www.15wanjia.com/news/96532.html

相关文章:

  • 美食网站的建设开题报告网络营销课程心得体会
  • 河南便宜网站建设价格windows优化大师有用吗
  • 自己怎么用h5做网站上海网站seo策划
  • 网站建设搭建专业网站平台公司seo广告优化
  • 长沙做痔疮东大医院L网站seo对网站优化
  • 广告发布登记某网站seo策划方案
  • 自学做网站要多久自动点击器下载
  • 大连疫情最新动态网站页面排名优化
  • 外贸开发网站公司如何搜索网页关键词
  • 竭诚网络网站建设开发学生没钱怎么开网店
  • phpcms v9农业网站模板域名注册管理中心网站
  • python 兼职网站开发企业官网
  • 韶关网站建设第一品牌网站点击量软件
  • 长沙网络建站磁力狗
  • 网站建设需要哪些软件如何制作一个个人网站
  • 兰州工业发展建设有限公司网站域名反查
  • 青岛网站建设哪家专业济南网站优化公司
  • 哪些网站可以看一级a做爰片网络推广属于什么专业
  • 上传商品的网站新产品上市推广策划方案
  • 网站建设内容是经营项目吗百度指数峰值查询
  • 如何做软件类型的网站中国互联网公司排名
  • 外贸网站建设盲区新媒体营销案例分析
  • 桂林网站建设百度seo推广工具
  • 做web网站有前途吗营销型企业网站诊断
  • 公司网站备案查询单页网站seo优化
  • 免费的源码分享网站深圳龙华区大浪社区
  • 网站建设综合推荐交换链接或称互惠链接
  • 柳市做公司网站建站工具
  • 做联盟 网站 跳转 防止垃圾外链seo优化与品牌官网定制
  • 做网站还有意义吗站长推广网