栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

追加不是线程安全的吗?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

追加不是线程安全的吗?

在Go中,没有值可以安全地进行并行读/写操作,切片(切片头)也不例外。

是的,您的代码存在数据竞争。运行带有

-race
选项的验证。

例:

type myClass struct {    AttributeName string}sourceSlice := make([]myClass, 100)destSlice := make([]myClass, 0)var wg sync.WaitGroupfor _, 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()

运行它

go run -race play.go

输出为:

==================WARNING: DATA RACERead at 0x00c420074000 by goroutine 6:  main.main.func1()      /home/icza/gows/src/play/play.go:20 +0x69Previous write at 0x00c420074000 by goroutine 5:  main.main.func1()      /home/icza/gows/src/play/play.go:20 +0x106Goroutine 6 (running) created at:  main.main()      /home/icza/gows/src/play/play.go:21 +0x1cbGoroutine 5 (running) created at:  main.main()      /home/icza/gows/src/play/play.go:21 +0x1cb====================================WARNING: DATA RACERead at 0x00c42007e000 by goroutine 6:  runtime.growslice()      /usr/local/go/src/runtime/slice.go:82 +0x0  main.main.func1()      /home/icza/gows/src/play/play.go:20 +0x1a7Previous write at 0x00c42007e000 by goroutine 5:  main.main.func1()      /home/icza/gows/src/play/play.go:20 +0xc4Goroutine 6 (running) created at:  main.main()      /home/icza/gows/src/play/play.go:21 +0x1cbGoroutine 5 (running) created at:  main.main()      /home/icza/gows/src/play/play.go:21 +0x1cb====================================WARNING: DATA RACEWrite at 0x00c420098120 by goroutine 80:  main.main.func1()      /home/icza/gows/src/play/play.go:20 +0xc4Previous write at 0x00c420098120 by goroutine 70:  main.main.func1()      /home/icza/gows/src/play/play.go:20 +0xc4Goroutine 80 (running) created at:  main.main()      /home/icza/gows/src/play/play.go:21 +0x1cbGoroutine 70 (running) created at:  main.main()      /home/icza/gows/src/play/play.go:21 +0x1cb==================Found 3 data race(s)exit status 66

解决方法很简单,使用一个

sync.Mutex
保护写
destSlice
值:

var (    mu        = &sync.Mutex{}    destSlice = make([]myClass, 0))var wg sync.WaitGroupfor _, 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并执行附加操作。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/413149.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号