我是古朗的初学者,我正在学习戈鲁蒂河和航道。从直觉上讲,我认为戈朗的大头针本质上是一个独立运行的线程。因此,如果有多个goroutine,执行命令将不会得到保证。因此,下面的代码应该以随机顺序输出"ping“和"pong”。然而,我观察到的是,这个程序依次产生"ping“和"pong”。有人能为我解释原因吗?任何答复都会有帮助。谢谢!
我发现的另一个有趣的观察是,如果我不调用打印机功能内的睡眠函数,程序将以随机顺序输出。
package main
import (
"fmt"
"time"
)
func pinger(c chan string) {
for i := 0; ; i++ {
c <- "ping"
}
}
func printer(c chan string) {
for {
msg := <- c
fmt.Println(msg)
time.Sleep(time.Second * 1)
}
}
func ponger(c chan string) {
for i := 0; ; i++ {
c <- "pong"
}
}
func main() {
var c chan string = make(chan string)
go pinger(c)
go ponger(c)
go printer(c)
var input string
fmt.Scanln(&input)
}
发布于 2018-03-05 04:36:48
Go程序设计语言规范 通道类型 容量(以元素数计)设置通道中缓冲区的大小。如果容量为零或缺失,则信道未缓冲,只有当发送方和接收方都准备就绪时,通信才能成功。
您有一个未缓冲的频道:make(chan string)
。
msg := <- c
(准备接收)和c <- "ping"
(准备发送):发送和接收"ping"
。
msg := <- c
(准备接收)和c <- "pong"
(准备发送):发送和接收"pong"
。
发布于 2018-03-05 05:03:29
为了更好地理解,请考虑以下语句和演示程序:
要真正看到这一点,您应该在您的机器上运行该程序:
package main
import (
"fmt"
"time"
)
func main() {
count := 10
c := make(chan int)
for i := 0; i < count; i++ {
go func(i int) {
c <- i + 1
}(i)
}
for i := 0; i < count; i++ {
fmt.Println("c", <-c)
}
fmt.Println()
d := make(chan int)
for i := 0; i < count; i++ {
go func(i int) {
d <- i + 1
}(i)
time.Sleep(time.Millisecond * 5)
}
for i := 0; i < count; i++ {
fmt.Println("d", <-d)
}
var input string
fmt.Scanln(&input)
}
这是一个游乐场,虽然并不是很明显,因为第一个组(c
)总是以一致的(尽管没有排序)的顺序出现。第二组(d
)总是按顺序出现在操场上或本地。
https://play.golang.org/p/JCVyVlFPRXS
这些是本地3次运行的输出。
1 2 3
----------------
c 2 c 10 c 10
c 1 c 4 c 2
c 6 c 1 c 1
c 3 c 2 c 4
c 4 c 3 c 3
c 5 c 7 c 5
c 8 c 5 c 8
c 7 c 6 c 7
c 9 c 8 c 9
c 10 c 9 c 6
d 1 d 1 d 1
d 2 d 2 d 2
d 3 d 3 d 3
d 4 d 4 d 4
d 5 d 5 d 5
d 6 d 6 d 6
d 7 d 7 d 7
d 8 d 8 d 8
d 9 d 9 d 9
d 10 d 10 d 10
https://stackoverflow.com/questions/49103221
复制相似问题