gpt4 book ai didi

go - 关闭一个 Go channel ,并同步一个 Go 例程

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

我无法在 go 中终止我的 WaitGroup,因此无法退出范围循环。谁能告诉我为什么。或者更好的方法来限制 go 例程的数量,同时仍然能够在 chan 关闭时退出!

我见过的大多数示例都与静态类型的 channel 长度有关,但此 channel 会因其他进程而动态调整大小。

示例中的打印语句(“DONE!”)显示 testValProducer 打印了正确的次数,但代码从未到达(“--EXIT--”),这意味着 wg.Wait 仍然以某种方式阻塞.

type TestValContainer chan string

func StartFunc(){
testValContainer := make(TestValContainer)
go func(){testValContainer <- "string val 1"}()
go func(){testValContainer <- "string val 2"}()
go func(){testValContainer <- "string val 3"}()
go func(){testValContainer <- "string val 4"}()
go func(){testValContainer <- "string val 5"}()
go func(){testValContainer <- "string val 6"}()
go func(){testValContainer <- "string val 7"}()
wg := sync.WaitGroup{}

// limit the number of worker goroutines
for i:=0; i < 3; i++ {
wg.Add(1)
go func(){
v := i
fmt.Printf("launching %v", i)
for str := range testValContainer{
testValProducer(str, &wg)
}
fmt.Println(v, "--EXIT --") // never called
}()
}

wg.Wait()
close(testValContainer)

}


func get(url string){
http.Get(url)
ch <- getUnvisited()
}


func testValProducer(testStr string, wg *sync.WaitGroup){
doSomething(testStr)
fmt.Println("done !") // called
wg.Done() // NO EFFECT??
}

最佳答案

我可能会做这样的事情,它让一切都容易理解。我定义了一个结构,它实现了一个信号量来控制活跃的 Go 例程的数量……并允许我在它们进入时从 channel 中读取。

package main

import (
"fmt"
"sync"
)

type TestValContainer struct {
wg sync.WaitGroup
sema chan struct{}
data chan int
}

func doSomething(number int) {
fmt.Println(number)
}

func main() {
//semaphore limit 10 routines at time
tvc := TestValContainer{
sema: make(chan struct{}, 10),
data: make(chan int),
}

for i := 0; i <= 100; i++ {
tvc.wg.Add(1)
go func(i int) {
tvc.sema <- struct{}{}
defer func() {
<-tvc.sema
tvc.wg.Done()
}()

tvc.data <- i
}(i)
}
// wait in the background so that waiting and closing the channel dont
// block the for loop below
go func() {
tvc.wg.Wait()
close(tvc.data)
}()
// get channel results
for res := range tvc.data {
doSomething(res)
}

}

关于go - 关闭一个 Go channel ,并同步一个 Go 例程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46130936/

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