与 GO 等待组同步
Synchronizing with a GO waitgroup
为什么这在示例 1 中是死锁,而在示例 2 中既不死锁也不打印任何内容?
示例 1.)
func main() {
w := sync.WaitGroup{}
w.Add(4)
c := make(chan int)
go func() { c <- 1; w.Done() }()
go func() { c <- 2; w.Done() }()
go func() { c <- 3; w.Done() }()
go func() { println(len(c)); w.Done() }()
w.Wait()
}
示例 2.)
func main() {
w := sync.WaitGroup{}
w.Add(3)
c := make(chan int)
go func() { c <- 1; w.Done() }()
go func() { c <- 2; w.Done() }()
go func() { c <- 3; w.Done() }()
go func() { w.Wait(); println(len(c)) }()
}
您的第一个示例启动了 3 个 goroutine,每个 goroutine 都尝试在 c
无缓冲通道上发送一个值。由于没有人从通道接收,所有这些都会阻塞。所以等待他们完成的 main()
也会被阻塞。所有 goroutine 都被阻塞:deadlock.
在您的第二个示例中,main()
函数“只是”启动 goroutine,之后不执行任何操作。当 main
goroutine 完成时(当你的 main()
函数 returns 时),你的应用程序也会结束,它不会等待其他非 main
goroutines 完成。有关详细信息,请参阅 。
在第一个示例中,通道将无法发送,因为未缓冲通道的另一端没有接收器。发送的将永远阻塞。因此等待组将永远等待。这是一个死锁情况,因为您的程序根本无法继续。
在第二种情况下,同样的事情发生了,但是你在一个单独的 goroutine 中等待。所以主要功能是能够继续。这不是一个完全的僵局。在这种情况下,继续意味着程序只是存在。
为什么这在示例 1 中是死锁,而在示例 2 中既不死锁也不打印任何内容?
示例 1.)
func main() {
w := sync.WaitGroup{}
w.Add(4)
c := make(chan int)
go func() { c <- 1; w.Done() }()
go func() { c <- 2; w.Done() }()
go func() { c <- 3; w.Done() }()
go func() { println(len(c)); w.Done() }()
w.Wait()
}
示例 2.)
func main() {
w := sync.WaitGroup{}
w.Add(3)
c := make(chan int)
go func() { c <- 1; w.Done() }()
go func() { c <- 2; w.Done() }()
go func() { c <- 3; w.Done() }()
go func() { w.Wait(); println(len(c)) }()
}
您的第一个示例启动了 3 个 goroutine,每个 goroutine 都尝试在 c
无缓冲通道上发送一个值。由于没有人从通道接收,所有这些都会阻塞。所以等待他们完成的 main()
也会被阻塞。所有 goroutine 都被阻塞:deadlock.
在您的第二个示例中,main()
函数“只是”启动 goroutine,之后不执行任何操作。当 main
goroutine 完成时(当你的 main()
函数 returns 时),你的应用程序也会结束,它不会等待其他非 main
goroutines 完成。有关详细信息,请参阅
在第一个示例中,通道将无法发送,因为未缓冲通道的另一端没有接收器。发送的将永远阻塞。因此等待组将永远等待。这是一个死锁情况,因为您的程序根本无法继续。
在第二种情况下,同样的事情发生了,但是你在一个单独的 goroutine 中等待。所以主要功能是能够继续。这不是一个完全的僵局。在这种情况下,继续意味着程序只是存在。