英文:
sync.WaitGroup - why one go routine comes after .wait()
问题
我得到的翻译结果如下:
从以下内容中我得到了:
收到的蛋糕包装:草莓蛋糕
收到的蛋糕包装:草莓蛋糕
收到的蛋糕包装:草莓蛋糕
收到的蛋糕包装:草莓蛋糕
我们完成了!
收到的蛋糕包装:草莓蛋糕
我没想到"我们完成了!"会是倒数第二个?
package main
import (
"fmt"
// "strconv"
// "time"
"sync"
)
func makeCakeAndSend(cs chan string, wg *sync.WaitGroup) {
cakeName := "草莓蛋糕"
cs <- cakeName
wg.Done()
}
func receiveCakeAndPack(cs chan string) {
for s := range cs {
fmt.Println("收到的蛋糕包装:", s)
}
}
func main() {
var wg sync.WaitGroup
cs := make(chan string)
wg.Add(5)
for i := 1; i <= 5; i++ {
go makeCakeAndSend(cs, &wg)
}
// go receiveCakeAndPack(cs)
go func() {
for s := range cs {
fmt.Println("收到的蛋糕包装:", s)
}
close(cs)
}()
wg.Wait()
fmt.Println("我们完成了!")
var input string
fmt.Scanln(&input)
}
英文:
From the following I get:<br>
Packing received cake: Strawberry Cake <br>
Packing received cake: Strawberry Cake <br>
Packing received cake: Strawberry Cake <br>
Packing received cake: Strawberry Cake <br>
We are done!<br>
Packing received cake: Strawberry Cake <br>
I did not expect "We are done!" to be second last?
package main
import (
"fmt"
// "strconv"
// "time"
"sync"
)
func makeCakeAndSend(cs chan string, wg *sync.WaitGroup) {
cakeName := "Strawberry Cake "
cs <- cakeName
wg.Done()
}
func receiveCakeAndPack(cs chan string) {
for s := range cs {
fmt.Println("Packing received cake: ", s)
}
}
func main() {
var wg sync.WaitGroup
cs := make(chan string)
wg.Add(5)
for i := 1; i <= 5; i++ {
go makeCakeAndSend(cs, &wg)
}
// go receiveCakeAndPack(cs)
go func() {
for s := range cs {
fmt.Println("Packing received cake: ", s)
}
close(cs)
}()
wg.Wait()
fmt.Println("We are done!")
var input string
fmt.Scanln(&input)
}
答案1
得分: 4
这是完全正常的。wg.Wait()
确保在继续之前,所有的 goroutine 都完成了向通道发送数据的操作,但它并不同步打印出 "Packing received cake"。
当每个人都完成向通道发送数据后,通道中会有一个项目,对吗?但是 Waitgroup 已经完成了。
因此,你会遇到一个竞争条件,主 goroutine 继续执行 "we are done",而接收 goroutine 接收并打印数据。这并不是同步的,你无法保证哪个会先发生。
英文:
It's perfectly normal. The wg.Wait()
makes sure that all goroutines finished sending data to the channel before we continue, it doesn't synchronize the prints of "Packing received cake".
When everyone has finished sending the data down the channel, the channel has one item in it, right? but the Waitgroup is finished.
So you have a race condition where the main goroutine continues to "we are done" and the receiving goroutine receives and prints. This is not synchronized and you have no guarantee which will happen first.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论