英文:
golang goroutine synchronization expected behaviour
问题
以下是代码的翻译:
下面的代码尝试在主goroutine上发送到通道,并从另一个goroutine接收,但有时会按预期返回,有时会在不打印任何内容的情况下退出。
package main
import "fmt"
func main() {
ch := make(chan bool)
go func() {
data := <-ch
fmt.Printf("Received: %t", data)
}()
ch <- true
}
同时,下面的代码每次都按预期工作,一个区别是添加了额外的检查以检查通道是否关闭,这总是产生相同的预期输出。这是否确保对通道的检查是必需的而不是可选的?或者代码有什么问题?
package main
import "fmt"
func main() {
ch := make(chan bool)
go func() {
data, ok := <-ch
if !ok {
fmt.Println("Channel closed")
return
}
fmt.Printf("Received: %t", data)
}()
ch <- true
}
英文:
The following piece of code try to send to the channel on the main goroutine and receive from another goroutine but a few times it returns as expected but a few times it exits without printing any on the console screen
package main
import "fmt"
func main() {
ch := make(chan bool)
go func() {
data := <-ch
fmt.Printf("Received: %t", data)
}()
ch <- true
}
At the same time, the following piece of code works as expected everytime, one difference is that an additional check has been added to check if the channel is closed or not which always throws the same expected output.
Does this ensure that a check on the channel is a must than optional ? or anything wrong with the code
package main
import "fmt"
func main() {
ch := make(chan bool)
go func() {
data, ok := <-ch
if !ok {
fmt.Println("Channel closed")
return
}
fmt.Printf("Received: %t", data)
}()
ch <- true
}
答案1
得分: 1
你应该在主例程退出之前等待 goroutine 完成。
package main
import (
"fmt"
"sync"
)
func main() {
ch := make(chan bool)
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
data := <-ch
fmt.Printf("接收到数据:%t", data)
}()
ch <- true
wg.Wait()
}
在这段代码中,我们使用了 sync.WaitGroup
来等待 goroutine 完成。在主例程中,我们创建了一个 chan bool
类型的通道 ch
,然后使用 wg.Add(1)
将等待组的计数器加一。接下来,我们启动了一个匿名的 goroutine,它会从通道 ch
中接收数据,并打印出接收到的数据。在 goroutine 的最后,我们使用 defer wg.Done()
来通知等待组计数器减一。然后,我们将 true
发送到通道 ch
中。最后,我们使用 wg.Wait()
来等待等待组中的计数器归零,确保 goroutine 完成后再退出主例程。
英文:
You should wait for goroutine to complete before main routine exit.
package main
import (
"fmt"
"sync"
)
func main() {
ch := make(chan bool)
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
data := <-ch
fmt.Printf("Received: %t", data)
}()
ch <- true
wg.Wait()
}
答案2
得分: -1
问题的翻译如下:
问题是你的第二段代码并不总是打印出"Received: true"。我进行了多次测试。
正如@jub0bs所提到的,不能保证你的goroutine在主程序之前完成。你必须自己进行控制。
英文:
The thing is your second piece of code doesn't print Received: true every time. I tested it several times.
As @jub0bs mentioned there is no guarantee that your goroutine finishes before the main routine. You must control it yourself.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论