英文:
Go WorkGroup doesn't synchronize functions
问题
这只是一个抽象的例子。只要test
从test2
接收到消息,它就会工作。然后当它们都完成后,将调用wg.Done()
,并在wg.Wait()
之后关闭应用程序。
package main
import (
"fmt"
"sync"
)
var a = make(chan bool)
var wg sync.WaitGroup
func main() {
go test()
wg.Add(1)
for i := 0; i < 5; i++ {
go test2()
wg.Add(1)
}
wg.Wait()
}
func test() {
defer wg.Done()
for {
val := <-a
fmt.Println(val)
}
}
func test2() {
defer wg.Done()
for i := 0; i < 3; i++ {
a <- true
}
}
至少在理论上是这样的,但在实践中并不适用。它正确地显示了15次true
,但之后应用程序因为死锁而崩溃,因为从未调用wg.Done()
。我感到困惑,因为这是教程中的做法。
英文:
This is just an abstract example. test
will work as long as it receives messages from test2
. Then when they are all done wg.Done()
will be called, and application will close after wg.Wait()
.
package main
import (
"fmt"
"sync"
)
var a = make(chan bool)
var wg sync.WaitGroup
func main() {
go test()
wg.Add(1)
for i := 0; i < 5; i++ {
go test2()
wg.Add(1)
}
wg.Wait()
}
func test() {
defer wg.Done()
for {
val := <-a
fmt.Println(val)
}
}
func test2() {
defer wg.Done()
for i := 0; i < 3; i++ {
a <- true
}
}
At least this is theory, but it doesn't translate well to practice. It correctly displays true
15 times, but then application crashes with a deadlock, because wg.Done()
is never called. I'm quite stumped, because this is how it's done in tutorials.
答案1
得分: 1
在test
函数中创建的goroutine将永远不会终止,因此等待组的计数永远不会达到零,程序将无限期等待。
在进行3次写入后终止无限循环,程序应该可以正常工作,因为你从通道中读取了3次。
此外,你必须在创建goroutine之前调用wg.Add
,而不是之后。在你添加到等待组之前可能会调用wg.Done
,导致恐慌。
英文:
The goroutine created in test
will never terminate, because of that, the wait group count will never reach zero and it will wait indefinitely.
Terminate the endless for-loop after 3 writes and the program should work, because you are reading 3 times from the channel.
Also, you have to call wg.Add
before creating the goroutine, not after. wg.Done
may be called before you can add to it, causing a panic.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论