英文:
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 (
"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)
}
why the x is -5 y is 17,is not the first goroutine blocked?
if
go sum(a[:len(a)/2], c)
x := <-c
go sum(a[len(a)/2:], c)
y := <-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 (
"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)
}
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
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论