我有以下一段 go 脚本,我对读取数据的通道和 go 例程的执行顺序有疑问。package mainimport "fmt"func squares(c chan int) { fmt.Println("started squares goroutine...") for num := range c { //num := <-c fmt.Println(num * num) } fmt.Println("exiting squares goroutine...")}func main() { fmt.Println("main() started") c := make(chan int, 3) go squares(c) c <- 1 printChannel(c) c <- 2 printChannel(c) c <- 3 printChannel(c) c <- 4 fmt.Println("after publish 4") printChannel(c) c <- 5 fmt.Println("after publish 5") printChannel(c) c <- 6 printChannel(c) c <- 7 printChannel(c) c <- 8 printChannel(c) fmt.Println("main() stopped")}func printChannel(c chan int) { fmt.Println("length: ",len(c)) fmt.Println("capacity: ",cap(c)) }输出:main() startedlength: 1capacity: 3length: 2capacity: 3length: 3capacity: 3started squares goroutine...14916after publish 4length: 0capacity: 3after publish 5length: 0capacity: 3length: 1capacity: 3length: 2capacity: 3length: 3capacity: 3main() stopped问题:创建的通道 ch 的容量为 3,但在将 4 发布到通道之前,通道不会在方块 go 例程中读取,如果容量为 3,其中 4 存储在通道中将所有数字从通道中读取出来后,再次将数字 5 发布到通道,但通道的长度仍然为 0,为什么?代码的 Goplayground 链接:https: //play.golang.org/p/TmCcZt5n58f
1 回答
汪汪一只猫
TA贡献1898条经验 获得超8个赞
无法保证 goroutine 的执行顺序,也无法保证 goroutine 何时中断(I/O,包括打印到 stdout,将是重新调度的最常见原因)。
对于您的第一个问题:您可以看到16之前正在打印after publish 4。这意味着squaresgoroutine 在主 goroutine 开始打印信息之前从通道读取并打印正方形。当主 goroutine 尝试打印通道的长度时,4它已经消失了。
同样,发送5到通道后,squaresgoroutine 已经收到了,但还没有打印出来。它在打印之前被中断。这意味着通道又是空的,但我们还没有看到25。
如果您多次运行示例,您将看到不同的输出。有时squaresgoroutine 会一直上升到64,有时不会。这是完全正常的。在普通代码中,您需要确保在退出之前等待数据被使用,并且您不会依赖于不同 goroutine 的执行顺序或时间。
- 1 回答
- 0 关注
- 201 浏览
添加回答
举报
0/150
提交
取消
