与GO等待组同步

huangapple go评论85阅读模式
英文:

Synchronizing with a GO waitgroup

问题

为什么示例1会发生死锁,而示例2不会发生死锁,也不会打印任何内容?

示例1中发生死锁的原因是在最后一个goroutine中,它尝试打印通道c的长度,但是在此之前,主goroutine已经调用了w.Wait(),等待所有的goroutine完成。然而,通道c中的值并没有被读取,因此最后一个goroutine无法继续执行,导致死锁。

示例2中没有发生死锁的原因是在最后一个goroutine中,它调用了w.Wait()等待所有的goroutine完成,然后才打印通道c的长度。这样做可以确保在打印之前,所有的goroutine都已经完成了它们的任务,避免了死锁的发生。

英文:

Why is this a deadlock in example 1, and does not deadlock nor print anything in example 2 ?

Example 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()
}

Example 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)) }()
}

答案1

得分: 1

在第一个例子中,由于无缓冲通道的另一端没有接收者,通道将无法发送。发送操作将永远阻塞,因此等待组将永远等待。这是一个死锁的情况,因为你的程序无法继续执行。

在第二个例子中,发生了同样的情况,但你在一个单独的goroutine中等待。因此,主函数能够继续执行。这不是一个完全的死锁。在这种情况下,继续执行意味着程序只是退出。

英文:

In the first example, the channels won't be able to send since there is no receiver on the other end of the unbuffered channel. The sent will block forever. And therefore the waitgroup will wait forever. This is a deadlock situation as your program is not able to continue at all.

In the second case, the same thing happens, but you wait in a separate goroutine. So the main function is able to continue. It's not a complete deadlock. In this case, the continuation means the program just exists.

答案2

得分: 0

你的第一个示例启动了3个goroutine,每个goroutine都试图在未缓冲的通道c上发送一个值。由于没有人从通道接收,所有这些操作都会被阻塞。因此,等待它们完成的main()函数也会被阻塞。所有的goroutine都被阻塞:死锁。

在你的第二个示例中,main()函数只是启动了goroutine,并在此之后没有做任何事情。当main goroutine完成时(当你的main()函数返回时),你的应用程序也会结束,它不会等待其他非main goroutine 完成。有关详细信息,请参阅https://stackoverflow.com/questions/28958192/no-output-from-goroutine/28958240#28958240。

英文:

Your first example launches 3 goroutines, and each tries to send a value on the c unbuffered channel. Since no one receives from the channel, all these will block. So the main() waiting for them to complete, will also be blocked. All goroutines are blocked: deadlock.

In your second example the main() function "just" launches goroutines and does not do anything after that. And when the main goroutine finishes (when your main() function returns), your app ends as well, it does not wait for other non-main goroutines to finishes. For details, see https://stackoverflow.com/questions/28958192/no-output-from-goroutine/28958240#28958240.

huangapple
  • 本文由 发表于 2022年2月8日 20:48:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/71034203.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定