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

Channel types

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


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

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

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

另一答案

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

  1. 阻止通道上的发送将按尝试发送的顺序进行服务。我对这一点并不是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执行命令的主要内容,如果未能解决你的问题,请参考以下文章

Goroutine执行命令

goroutine简介

如果包含 time.Sleep,Goroutine 不会执行

go 等待所有 goroutine 执行结束的方法

Golang之goroutine

与通道和 goroutine 同步