gooroutine有优先权吗?

时间:2016-04-09 08:21:23

标签: go

Golang fish,寻求解释。

Goroutine是否有优先权?

package main

import (
  "fmt"
)

func sum(a []int, c chan int) {
  var total int
  for _, v := range a {
    total += v
  }
  c <- total
}

func main() {
  a := []int{7, 2, 8, -9, 4, 0}
  c := make(chan int)
  go sum(a[:len(a)/2], c)
  go sum(a[len(a)/2:], c)

  // x, y := <-c, <-c
  x := <-c
  y := <-c
  fmt.Println(x, y, x+y)
}

为什么x是-5 y是17,是不是第一个goroutine被阻止了? 如果

go sum(a[:len(a)/2], c)
x := <-c
go sum(a[len(a)/2:], c)
y := <-c

这个顺序是对的。为什么...

1 个答案:

答案 0 :(得分:0)

在第一个示例中,输出应为-5 17 1217 -5 12。两个goroutine同时运行(同时)。任何goroutine首先完成的结果将存储在变量x中。另一个goroutine的结果存储在y中。为了更好地看到goroutine同时运行,您可以在函数sum()中放置一个随机计时器。这样,你应该看到不同运行之间的输出变化,因为一个goroutine随机需要比另一个更长的时间:

package main

import (
    "fmt"
    "time"
    "math/rand"
)

func sum(a []int, c chan int) {
    time.Sleep(time.Duration(rand.Intn(1000000)))   // wait for up to 1ms
    total := 0
    for _, v := range a {
        total += v
    }
    c <- total
}

func main() {
    rand.Seed(time.Now().Unix())
    a := []int{7, 2, 8, -9, 4, 0}
    c := make(chan int)
    go sum(a[:len(a)/2], c)
    go sum(a[len(a)/2:], c)

    x := <-c
    y := <-c
    fmt.Println(x, y, x+y)
}

在你的第二个例子中,你正在开始第一个goroutine。然后你从频道c中读取,这是一个阻止操作(意味着它会等到结果=&gt;第一个goroutine完成)。此处的输出是确定性的,始终为17 -5 12