我是 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 函数是否会在接收后执行下一行。
- 3 回答
- 0 关注
- 188 浏览
添加回答
举报
0/150
提交
取消