我是一个新的围棋学习者,我正在跟随gobyexample.com学习基础知识。当我到达“关闭通道”部分时,本教程将插入以下代码片段(我将删除原始注释):
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因此,我理解通道的“队列”(我知道这个术语并不是最准确的,但为了了解自己,它就是我对通道是什么的理解)是5大小的,所以前10条日志消息对我来说很好。
但是,信息6和13如何在实际发送之前输出?如果通道大小为5,如何连续发送7条消息?我漏掉了什么?
发布于 2019-05-28 13:56:51
Goroutines同时运行,因此它们也同时打印到stdout (即无序)。此外,fmt.Print API是缓冲的,因此您的打印文件实际上不会在调用它们时立即进行排序。这种情况在其他语言中也会发生。
这就是为什么您不能从stdout中的消息中派生出goroutines的真正并发执行。
发布于 2019-05-28 13:54:55
但是,信息6和13如何在实际发送之前输出?
我们只知道fmt.Println("received job", j)是在打印fmt.Println("sent job", j)之前打印的,这在并发工作代码中是可信的。
如果通道大小为5,如何连续发送7条消息?
同样,因为我们不知道哪个语句会首先打印出来,这是可以预料的。队列已经可以减少,我们仍然在打印。
https://stackoverflow.com/questions/56343626
复制相似问题