gpt4 book ai didi

go - slice 的长度在已经使用 WaitGroup 时有所不同

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

我很难理解并发/并行。在我的代码中,我做了一个 5 循环的循环。在循环内部,我添加了 wg.Add(1),总共有 5 个 Add。这是代码:

package main

import (
"fmt"
"sync"
)

func main() {
var list []int
wg := sync.WaitGroup{}
for i := 0; i < 5; i++ {
wg.Add(1)
go func(c *[]int, i int) {
*c = append(*c, i)
wg.Done()
}(&list, i)
}
wg.Wait()
fmt.Println(len(list))
}

main func 等到所有 goroutine 完成,但是当我尝试打印 slice 的长度时,我得到了随机结果。 ex (1,3,etc) 是否缺少某些东西才能获得预期的结果,即 5 ?

最佳答案

is there something that is missing for it to get the expected result ie 5 ?

是的,适当的同步。如果多个 goroutine 访问同一个变量,其中至少有一个是写入,则需要显式同步。

您的示例可以使用单个互斥体“保护”:

var list []int
wg := sync.WaitGroup{}

mu := &sync.Mutex{} // A mutex

for i := 0; i < 5; i++ {
wg.Add(1)
go func(c *[]int, i int) {
mu.Lock() // Must lock before accessing shared resource
*c = append(*c, i)
mu.Unlock() // Unlock when we're done with it
wg.Done()
}(&list, i)
}
wg.Wait()

fmt.Println(len(list))

这将始终打印 5。

注意:在末尾读取同一个 slice 以打印其长度,但我们没有在那里使用互斥锁。这是因为使用 waitgroup 确保我们只能在所有修改它的 goroutines 完成他们的工作后才能到达那个点,所以那里不会发生数据竞争。但一般来说,读取和写入都必须同步。

查看可能的重复项:

go routine not collecting all objects from channel

Server instances with multiple users

Why does this code cause data race?

How safe are Golang maps for concurrent Read/Write operations?

golang struct concurrent read and write without Lock is also running ok?

查看相关问题:

Can I concurrently write different slice elements

If I am using channels properly should I need to use mutexes?

Is it safe to read a function pointer concurrently without a lock?

Concurrent access to maps with 'range' in Go

关于go - slice 的长度在已经使用 WaitGroup 时有所不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51675437/

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