gpt4 book ai didi

go - 如果没有互斥体,并发处理 slice 无法按预期工作

转载 作者:数据小太阳 更新时间:2023-10-29 03:41:15 24 4
gpt4 key购买 nike

函数 WithMutexWithoutMutex 给出了不同的结果。

WithoutMutex 实现正在丢失值,即使我设置了 Waitgroup

有什么问题吗?

Do not run on Playground

附言我使用的是 Windows 10 和 Go 1.8.1

package main

import (
"fmt"
"sync"
)

var p = fmt.Println

type MuType struct {
list []int
*sync.RWMutex
}

var muData *MuType
var data *NonMuType

type NonMuType struct {
list []int
}

func (data *MuType) add(i int, wg *sync.WaitGroup) {
data.Lock()
defer data.Unlock()
data.list = append(data.list, i)
wg.Done()

}

func (data *MuType) read() []int {
data.RLock()
defer data.RUnlock()
return data.list
}

func (nonmu *NonMuType) add(i int, wg *sync.WaitGroup) {
nonmu.list = append(nonmu.list, i)
wg.Done()

}

func (nonmu *NonMuType) read() []int {
return nonmu.list
}

func WithoutMutex() {
nonmu := &NonMuType{}
nonmu.list = make([]int, 0)
var wg = sync.WaitGroup{}
for i := 0; i < 10; i++ {
wg.Add(1)
go nonmu.add(i, &wg)

}
wg.Wait()
data = nonmu
p(data.read())
}

func WithMutex() {
mtx := &sync.RWMutex{}
withMu := &MuType{list: make([]int, 0)}
withMu.RWMutex = mtx
var wg = sync.WaitGroup{}
for i := 0; i < 10; i++ {
wg.Add(1)
go withMu.add(i, &wg)
}
wg.Wait()
muData = withMu
p(muData.read())
}

func stressTestWOMU(max int) {
p("Without Mutex")
for ii := 0; ii < max; ii++ {
WithoutMutex()
}
}

func stressTest(max int) {
p("With Mutex")
for ii := 0; ii < max; ii++ {
WithMutex()
}
}

func main() {
stressTestWOMU(20)
stressTest(20)
}

最佳答案

slice 对于并发写入是不安全的,所以我一点也不惊讶 WithoutMutex 看起来根本不一致,并且已经删除了项目。

WithMutex 版本一直有 10 个项目,但顺序困惑。这也是意料之中的,因为互斥量保护它,以便一次只能追加一个。虽然无法保证哪个 goroutine 将以哪个顺序运行,因此这是一场竞赛,看哪个快速生成的 goroutine 将首先附加。

WaitGroup 不做任何事情来控制访问或强制排序。它只是在最后提供一个信号,表明一切都已完成。

关于go - 如果没有互斥体,并发处理 slice 无法按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43799555/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com