Goroutine执行命令
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Goroutine执行命令相关的知识,希望对你有一定的参考价值。
我是golang的初学者,我正在学习goroutine和频道。直觉上,我认为golang中的gorountine本质上是一个独立运行的线程。因此,如果有多个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)
}
答案
The Go Programming Language Specification
容量(以元素数量)设置通道中缓冲区的大小。如果容量为零或不存在,则通道无缓冲,只有当发送方和接收方都准备就绪时,通信才会成功。
你有一个无缓冲的频道:make(chan string)
。
msg := <- c
(准备接收)和c <- "ping"
(准备发送):发送和接收"ping"
。
msg := <- c
(准备接收)和c <- "pong"
(准备发送):发送和接收"pong"
。
另一答案
为了更好地理解以下语句和演示程序:
- 阻止通道上的发送将按尝试发送的顺序进行服务。我对这一点并不是100%肯定,但是演示程序显示了这种行为,这[ticket] [1]提到在2年前实现这种行为。
要真正看到这一点,你应该在你的机器上运行:
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
以上是关于Goroutine执行命令的主要内容,如果未能解决你的问题,请参考以下文章