Go WorkGroup无法同步函数。

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

Go WorkGroup doesn't synchronize functions

问题

这只是一个抽象的例子。只要testtest2接收到消息,它就会工作。然后当它们都完成后,将调用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 (
	&quot;fmt&quot;
	&quot;sync&quot;
)

var a = make(chan bool)
var wg sync.WaitGroup

func main() {
	go test()
	wg.Add(1)
	for i := 0; i &lt; 5; i++ {
		go test2()
		wg.Add(1)
	}
	wg.Wait()
}

func test() {
	defer wg.Done()
	for {
		val := &lt;-a
		fmt.Println(val)
	}
}

func test2() {
	defer wg.Done()
	for i := 0; i &lt; 3; i++ {
		a &lt;- 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.

huangapple
  • 本文由 发表于 2023年3月16日 23:00:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/75757990.html
匿名

发表评论

匿名网友

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

确定