【发布时间】:2018-02-18 05:36:21
【问题描述】:
我无法在 go 中终止我的 WaitGroup,因此无法退出范围循环。谁能告诉我为什么。或者是一种更好的方法来限制 go 例程的数量,同时仍然能够在 chan 关闭时退出!
我见过的大多数示例都与静态类型的 chan 长度有关,但该通道会因其他进程而动态调整大小。
打印示例中的打印语句 ("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??
}
【问题讨论】:
-
没有可以动态调整大小的通道,但代码中没有任何内容表明您是如何尝试这样做的。您正在复制您的 WaitGroup,
go vet会为您指出此错误 -
抱歉,动态调整大小是指无缓冲的频道“去检查”?
-
无缓冲通道没有缓冲区,因此它的“大小”永远不会是 0。
vet是内置工具之一,在此代码上运行它。 -
谢谢我已经更新了,问题还没解决问题,页面脚本仍然无法到达打印语句
-
你应该只为每个 goroutine 调用
wg.Done,但你为从testValContainer收到的每个值调用它。我不确定逻辑应该是什么,因此很难提供正确的答案。你想完成什么。
标签: go concurrency channel goroutine