【发布时间】:2020-04-25 13:53:08
【问题描述】:
我正在尝试理解 Goroutine 中的同步。我在这里有一个代码,它在通道上写入 0 到 4 的数字,完成后我使用 range 从通道读取并打印值。
下面的代码在我等待使用 wg.Wait() 并在单独的 Goroutine 中关闭通道时运行良好。
package main
import (
"fmt"
"strconv"
"sync"
)
func putvalue(i chan string, value string, wg *sync.WaitGroup) {
i <- value
defer wg.Done()
}
func main() {
queue := make(chan string)
var wg sync.WaitGroup
for i := 0; i < 5; i++ {
wg.Add(1)
go putvalue(queue, strconv.Itoa(i), &wg)
}
go func() {
wg.Wait()
close(queue)
}()
for elem := range queue {
fmt.Println(elem)
}
}
https://play.golang.org/p/OtaRP3Mm4lk
但如果我使用完全相同的代码,但在主线程中等待并关闭通道,则会导致死锁。下面的代码导致死锁。
package main
import (
"fmt"
"strconv"
"sync"
)
func putvalue(i chan string, value string, wg *sync.WaitGroup) {
i <- value
defer wg.Done()
}
func main() {
queue := make(chan string)
var wg sync.WaitGroup
for i := 0; i < 5; i++ {
wg.Add(1)
go putvalue(queue, strconv.Itoa(i), &wg)
}
wg.Wait()
close(queue)
for elem := range queue {
fmt.Println(elem)
}
}
https://play.golang.org/p/JXmdsdPKQPu
据我了解,在第二种情况下,主线程执行停止并等待,但它与在单独的 goroutine 中执行它有什么不同?请帮助我理解这一点。
【问题讨论】: