协程(goroutine)是否有优先级?

huangapple go评论79阅读模式
英文:

gooroutine is have a priority or not?

问题

Golang鱼,寻求解释。

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

这个顺序是正确的。为什么呢?

英文:

Golang fish,Seeking explanation.

Goroutine is have a priority or not?

package main

import (
  &quot;fmt&quot;
)

func sum(a []int, c chan int) {
  var total int
  for _, v := range a {
	total += v
  }
  c &lt;- 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 := &lt;-c, &lt;-c
  x := &lt;-c
  y := &lt;-c
  fmt.Println(x, y, x+y)
}

why the x is -5 y is 17,is not the first goroutine blocked?
if

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

this order is right. why。。。

答案1

得分: 0

在你的第一个示例中,输出应该是-5 17 12或者17 -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)))	// 等待最多1毫秒
	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中读取(这是一个阻塞操作,意味着它会等待直到有结果=>第一个goroutine完成)。这里的输出是确定性的,将始终是17 -5 12

英文:

In your first example, the output should be either -5 17 12 or 17 -5 12. Both goroutines are running concurrently (at the same time). The result of whichever goroutine finishes first will be stored in the variable x. The result of the other goroutine is stored in y. In order to better see that the goroutines are running concurrently, you can put a random timer inside the function sum(). This way, you should see the output change between different runs, because one goroutine randomly takes longer than the other:

package main

import (
	&quot;fmt&quot;
	&quot;time&quot;
	&quot;math/rand&quot;
)

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 &lt;- 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 := &lt;-c
	y := &lt;-c
    fmt.Println(x, y, x+y)
}

In your second example, you are starting the first goroutine. Then you read from the channel c, which is a blocking operation (meaning it will wait until there's a result => the first goroutine is done). The output here is deterministic and will always be 17 -5 12.

huangapple
  • 本文由 发表于 2016年4月9日 16:21:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/36514462.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定