首页 > 后端开发 > Golang > 正文

为什么在 Go 中附加到切片是线程不安全的?

Susan Sarandon
发布: 2024-11-09 17:30:02
原创
238 人浏览过

Why is appending to slices in Go thread-unsafe?

为什么追加到切片可能是线程不安全的

当多个 goroutine 尝试同时将数据追加到切片时,数据竞争条件可能会发生发生。这是因为 Go 中的切片不是线程安全的,这意味着多个 goroutine 可以同时访问和修改同一个切片头,这可能会导致数据损坏。

数据争用说明

考虑以下代码:

destSlice := make([]myClass, 0)

var wg sync.WaitGroup
for _, myObject := range sourceSlice {
    wg.Add(1)
    go func(closureMyObject myClass) {
        defer wg.Done()
        var tmpObj myClass
        tmpObj.AttributeName = closureMyObject.AttributeName
        destSlice = append(destSlice, tmpObj)
    }(myObject)
}
wg.Wait()
登录后复制

在此代码中,多个 Goroutines 并发附加到 destSlice切片。这可能会导致结果切片中数据丢失或空白,因为 goroutine 可能会交错其操作并覆盖彼此的更改。

使用“-race”选项验证数据争用

使用“-race”选项运行代码将为检测到的每个数据争用生成警告。以下输出说明了所提供代码中的数据竞争条件:

==================
WARNING: DATA RACE
Read at 0x00c420074000 by goroutine 6:
  main.main.func1()
      /home/icza/gows/src/play/play.go:20 +0x69

Previous write at 0x00c420074000 by goroutine 5:
  main.main.func1()
      /home/icza/gows/src/play/play.go:20 +0x106

Goroutine 6 (running) created at:
  main.main()
      /home/icza/gows/src/play/play.go:21 +0x1cb

Goroutine 5 (running) created at:
  main.main()
      /home/icza/gows/src/play/play.go:21 +0x1cb
==================
登录后复制

解决方案:使用互斥体进行同步

为了确保线程安全的并发追加,您可以可以使用互斥体来保护 destSlice 切片头。以下修改后的代码演示了这一点:

var (
    mu        = &sync.Mutex{}
    destSlice = make([]myClass, 0)
)

var wg sync.WaitGroup
for _, myObject := range sourceSlice {
    wg.Add(1)
    go func(closureMyObject myClass) {
        defer wg.Done()
        var tmpObj myClass
        tmpObj.AttributeName = closureMyObject.AttributeName
        mu.Lock()
        destSlice = append(destSlice, tmpObj)
        mu.Unlock()
    }(myObject)
}
wg.Wait()
登录后复制

通过在每次追加操作之前获取互斥体,可以防止多个 goroutine 同时修改切片头,从而确保数据完整性并消除数据竞争条件。

以上是为什么在 Go 中附加到切片是线程不安全的?的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责声明 Sitemap
PHP中文网:公益在线PHP培训,帮助PHP学习者快速成长!