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

Append 函数对于并发 Goroutine 使用是线程安全的吗?

Mary-Kate Olsen
发布: 2024-11-18 21:53:02
原创
857 人浏览过

Is Append Function Thread-Safe for Concurrent Goroutine Usage?

多个 Goroutine 并发使用时 Append 不是线程安全的吗?

当使用 Goroutine 在循环内并发向切片追加数据时,您可能会遇到不一致的情况,例如缺少或重复的元素。这种情况提出了一个问题:append 函数对于多个 goroutine 并发使用是否不是线程安全的。

答案:数据争用和缺乏线程安全

在 Go 中,没有任何值对于并发读/写是安全的,包括切片(或更具体地说,切片头)。当多个 goroutine 尝试同时修改同一个切片时,会发生数据争用,可能会导致意外行为。

数据争用验证

您可以使用以下命令运行代码 -竞赛选项来确认数据竞赛的存在:

go run -race play.go
登录后复制

解决方案:同步

为了解决这个问题并保证数据的一致性,需要在并发写入元素时同步对切片的访问。这可以使用sync.Mutex来实现:

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 具有写访问权限,从而防止数据损坏。

结论

虽然切片元素表现为不同的变量并且可以修改同时,切片头本质上并不是线程安全的。为了确保安全一致的并发写入操作,在修改 goroutine 内的切片头时采用同步机制(例如互斥锁或通道)至关重要。

以上是Append 函数对于并发 Goroutine 使用是线程安全的吗?的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板