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

Go同步和并发模型

Go同步和并发模型

Go
至尊宝的传说 2023-06-19 16:59:41
我是一名新的 Go 学习者,当我到达&ldquo;关闭频道&rdquo;部分时,教程会插入此代码片段(我将删除原始评论):    package main    import "fmt"    func main() {        jobs := make(chan int, 5)        done := make(chan bool)       go func() {           for {               j, more := <-jobs               if more {                   fmt.Println("received job", j)               } else {                   fmt.Println("received all jobs")                   done <- true                   return               }           }       }()       for j := 1; j <= 18; j++ {           jobs <- j           fmt.Println("sent job", j)       }       close(jobs)       fmt.Println("sent all jobs")       <-done    }原始代码在作业发送者循环中设置 3 而不是 18。在play.golang.org中执行这段代码是我不完全理解的。它总是输出以下内容:sent job 1sent job 2sent job 3sent job 4sent job 5received job 1received job 2received job 3received job 4received job 5received job 6sent job 6sent job 7sent job 8sent job 9sent job 10sent job 11sent job 12received job 7received job 8received job 9received job 10received job 11received job 12received job 13sent job 13sent job 14sent job 15sent job 16sent job 17sent job 18sent all jobsreceived job 14received job 15received job 16received job 17received job 18received all jobs所以我知道一个频道的&ldquo;队列&rdquo;(我知道这个术语不是最准确的,但为了自己学习,这是我对频道的理解)的大小为 5,所以前 10日志消息对我来说很好。但是消息 6 和 13 如何在实际发送之前输出它们的接收信息呢?如果通道大小为 5,如何连续发送 7 条消息?我错过了什么?
查看完整描述

2 回答

?
炎炎设计

TA贡献1808条经验 获得超4个赞

Goroutines 同时运行,因此它们也同时打印到标准输出(即无序)。此外,fmt.Print API 是缓冲的,因此您的打印实际上不会在调用时立即打印。这也发生在其他语言中。

这就是为什么您无法从 stdout 中的消息中导出 goroutine 的真正并发执行。


查看完整回答
反对 回复 2023-06-19
?
牧羊人nacy

TA贡献1862条经验 获得超7个赞

但是消息 6 和 13 如何在实际发送之前输出它们的接收信息呢?

我们只知道fmt.Println("received job", j)was printed before fmt.Println("sent job", j)was printed,这在并发工作代码中是合理的。

如果通道大小为 5,如何连续发送 7 条消息?

同样,因为我们不确切知道哪个语句首先打印出来,所以这是可以预料的。队列已经可以减少,我们仍在打印。


查看完整回答
反对 回复 2023-06-19
  • 2 回答
  • 0 关注
  • 88 浏览
慕课专栏
更多

添加回答

举报

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