Goroutine执行命令

时间:2018-03-05 03:49:02

标签: go concurrency 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)
}

2 个答案:

答案 0 :(得分:2)

  

The Go Programming Language Specification

     

Channel types

     

容量(以元素数量)设置缓冲区的大小   这个频道。如果容量为零或不存在,则通道为   无缓冲和通信只有当发送者和发送者都成功时才会成功   接收器准备就绪。

您有一个无缓冲的频道:make(chan string)

msg := <- c(准备好接收)和c <- "ping"(准备发送):发送和接收"ping"

msg := <- c(已准备好接收)和c <- "pong"(准备发送):发送和接收"pong"

答案 1 :(得分:0)

为了更好地理解以下语句和演示程序:

  1. 将按照尝试发送的顺序为被阻止的频道发送服务。我对这一点并不是100%肯定,但是演示程序显示了这种行为,而[ticket] [1]提到在2年前实现了这种行为。
  2. 要真正看到这一点,你应该在你的机器上运行它:

    c

    这是一个游乐场,虽然它不会显而易见发生的事情,因为第一组(d)将始终以一致(但未排序)的顺序出现。第二组( 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://play.golang.org/p/JCVyVlFPRXS

    这些是本地3次运行的输出

    MyFirebaseInstanceIDService