猿问

Go同步和并发模型

我是一名新的 Go 学习者,当我到达“关闭频道”部分时,教程会插入此代码片段(我将删除原始评论):

    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 1

sent job 2

sent job 3

sent job 4

sent job 5

received job 1

received job 2

received job 3

received job 4

received job 5

received job 6

sent job 6

sent job 7

sent job 8

sent job 9

sent job 10

sent job 11

sent job 12

received job 7

received job 8

received job 9

received job 10

received job 11

received job 12

received job 13

sent job 13

sent job 14

sent job 15

sent job 16

sent job 17

sent job 18

sent all jobs

received job 14

received job 15

received job 16

received job 17

received job 18

received all jobs

所以我知道一个频道的&ldquo;队列&rdquo;(我知道这个术语不是最准确的,但为了自己学习,这是我对频道的理解)的大小为 5,所以前 10日志消息对我来说很好。


但是消息 6 和 13 如何在实际发送之前输出它们的接收信息呢?如果通道大小为 5,如何连续发送 7 条消息?我错过了什么?


至尊宝的传说
浏览 123回答 2
2回答

炎炎设计

Goroutines 同时运行,因此它们也同时打印到标准输出(即无序)。此外,fmt.Print API 是缓冲的,因此您的打印实际上不会在调用时立即打印。这也发生在其他语言中。这就是为什么您无法从 stdout 中的消息中导出 goroutine 的真正并发执行。

牧羊人nacy

但是消息 6 和 13 如何在实际发送之前输出它们的接收信息呢?我们只知道fmt.Println("received job", j)was printed before&nbsp;fmt.Println("sent job", j)was printed,这在并发工作代码中是合理的。如果通道大小为 5,如何连续发送 7 条消息?同样,因为我们不确切知道哪个语句首先打印出来,所以这是可以预料的。队列已经可以减少,我们仍在打印。
随时随地看视频慕课网APP

相关分类

Go
我要回答