gpt4 book ai didi

go - 从不同的 go 例程将数据写入同一 channel ,无需 WaitGroup 即可正常工作

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

在等待 wg.Wait() 后,当使用多个带 WaitGroup 的 go 例程将数据写入同一 channel 时,出现异常,表示所有 go 例程都处于休眠状态或锁死状态。

package main

import (
"fmt"
"runtime"
"sync"
)

var wg sync.WaitGroup

func CreateMultipleRoutines() {
ch := make(chan int)

for i := 0; i < 10; i++ { // creates 10 go routines and adds to waitgroup
wg.Add(1)
go func() {
for j := 0; j < 10; j++ {
ch <- j
}
wg.Done() // indication of go routine is done to main routine
}()
}

fmt.Println(runtime.NumGoroutine())
wg.Wait() //wait for all go routines to complete
close(ch) // closing channel after completion of wait fo go routines
for v := range ch { // range can be used since channel is closed
fmt.Println(v)
}
fmt.Println("About to exit program ...")
}

当尝试在没有 WaitGroup 的情况下实现这一点时,我能够通过循环将数据推送到 channel 的确切次数从 channel 读取数据,但我无法调整范围,因为当我们关闭 channel 时会出现 panic 。这是示例代码

package main

import (
"fmt"
"runtime"
)

func main() {
ch := make(chan int)


for i := 0; i < 10; i++ { // creates 10 go routines and adds to waitgroup
go func(i int) {
for j := 0; j < 10; j++ {
ch <- j * i
}
}(i)
}

fmt.Println(runtime.NumGoroutine())

for v := 0; v < 100; v++ {
fmt.Println(<-ch)
}
fmt.Println("About to exit program ...")
}

我想了解为什么等待状态下的 WaitGroup 仍在等待,即使所有 go routines 都发出 Done() 信号,这又使 go routines 的数量为零

最佳答案

我认为您的原始代码存在一些问题。

  1. 您正在关闭 channel ,然后再阅读。
  2. 由于您的 channel “大小”为 1,因此您无法获得使用 10 个 goroutine 的优势。所以一个 goroutine 每次产生一个结果。

我的解决方案是生成一个新的 goroutine 来监控 10 个 goroutine 是否完成了它的工作。在那里您将使用您的 WaitGroup

那么代码会是这样的:

package main

import (
"fmt"
"runtime"
"sync"
)

var wg sync.WaitGroup

func main() {
ch := make(chan int, 10)

for i := 0; i < 10; i++ { // creates 10 go routines and adds to waitgroup
wg.Add(1)
go func() {
for j := 0; j < 10; j++ {
ch <- j
}
wg.Done() // indication of go routine is done to main routine
}()
}

go func(){
wg.Wait()
close(ch)
}()

fmt.Println(runtime.NumGoroutine())
for v := range ch { // range can be used since channel is closed
fmt.Println(v)
}
fmt.Println("About to exit program ...")
}

关于go - 从不同的 go 例程将数据写入同一 channel ,无需 WaitGroup 即可正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55103707/

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