为了账号安全,请及时绑定邮箱和手机立即绑定

Go 中的简单通道的竞争条件?

Go 中的简单通道的竞争条件?

Go
动漫人物 2021-07-10 16:03:21
我是 Go 的新手,并且对在带有 Go 1.2 版的 Linux 上运行的一小块代码似乎有点罕见的竞争条件感到困惑。基本上,我为 an 创建一个通道int,启动一个 go 例程从该通道读取,然后将单个 int 写入该通道。package mainimport "fmt"func main() {    channel := make(chan int)    go func() {        number := <- channel        fmt.Printf("GOT IT: %d\n", number)    }()    fmt.Println("[+] putting num on channel")    channel <- 42    fmt.Println("[-] putting num on channel")}大约 90% 的时间输出符合预期:$ go run test.go [+] putting num on channelGOT IT: 42[-] putting num on channel然而,大约有 10% 的时间,go 例程不会从通道中读取数字并且不打印任何内容:$ go run test.go [+] putting num on channel[-] putting num on channel我很困惑,因为这段代码与https://gobyexample.com/channels上的示例非常相似,(我没有这个问题),除了我在 go 例程中从通道读取而不是编写到频道。我是否对渠道的工作方式有根本的误解,或者这里还有其他东西在起作用吗?
查看完整描述

3 回答

?
桃花长相依

TA贡献1860条经验 获得超8个赞

您似乎希望接收 goroutine 在第二个fmt.Println执行之前运行完成。不能保证情况如此。如果程序终止,goroutine 不能保证到达其函数的末尾。


当你看到没有显示“GOT IT”消息的输出时,通道传递了它的消息,但main函数在 goroutine 之前完成。程序终止,goroutine 永远没有机会调用fmt.Printf


在您引用的示例中,该main函数以以下内容结尾:


go func() { messages <- "ping" }()

msg := <-messages

fmt.Println(msg)

由于main函数在收到消息之前会阻塞,因此在这个例子中 goroutine 总是运行到完成。在您的代码中,您的 goroutine 在从通道接收后执行一个步骤,并且未定义 goroutine 或 main 函数是否会在接收后执行下一行。


查看完整回答
反对 回复 2021-07-12
  • 3 回答
  • 0 关注
  • 188 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信