gpt4 book ai didi

Go lang, channel 处理顺序

转载 作者:数据小太阳 更新时间:2023-10-29 03:32:01 25 4
gpt4 key购买 nike

我正在通过'A tour of Go'学习Go lang,并且很难理解Go channel 的运行顺序,

package main

import "fmt"
import "time"

func sum(a []int, c chan int) {

sum := 0
for _, v := range a {
time.Sleep(1000 * time.Millisecond)
sum += v
}
c <- sum // send sum to c
}

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 // receive from c

fmt.Println(x, y, x+y)
fmt.Println("Print this first,")
}

如果在代码之上运行,我预计,

Print this first,
17 -5 12

因为,Go 例程以非阻塞方式运行,但是,实际上它会打印,

17 -5 12
Print this first,

我在网上找到的另一个例子,

package main

import "fmt"

type Data struct {
i int
}

func func1(c chan *Data ) {
fmt.Println("Called")
for {
var t *Data;
t = <-c //receive
t.i += 10 //increment
c <- t //send it back
}
}

func main() {
c := make(chan *Data)
t := Data{10}
go func1(c)
println(t.i)
c <- &t //send a pointer to our t
i := <-c //receive the result
println(i.i)
println(t.i)
}

此外,我预计,它首先打印“Called”,但结果是

10
20
20
Called

我误会了什么?请帮助我了解 Go routine 和 channel。

最佳答案

在您的第一个示例中,x, y := <-c, <-c将阻塞直到它读出 c两次,然后将值赋给 x, y .除了 channel ,您还有一个赋值、一个打印语句,然后是另一个打印语句。这些都是同步的事情,并且会按照您声明的顺序发生。第二个打印语句不可能先打印出来。

第二个是因为fmt.Println写入 STDOUT 和 println到标准错误。如果你保持一致(比如到处使用 println),那么你会看到:

10
Called
20
20

那是因为第一个 println(t.i) 之间存在竞争在主要和println("Called")这发生在 goroutine 中。我猜是 GOMAXPROCS设置为 1,这将持续发生。与 GOMAXPROCS设置为 NumCPU ,我得到了混合结果,有时看起来像上面,有时像这样:

10Called

20
20

关于Go lang, channel 处理顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32173373/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com