为了账号安全,请及时绑定邮箱和手机立即绑定

使用渠道下单

使用渠道下单

Go
湖上湖 2023-07-31 15:25:02
我从 Go 旅游中有这个代码:func sum(s []int, c chan int) {    sum := 0    for _, v := range s {        sum += v    }    fmt.Printf("Sending %d to chan\n", sum)    c <- sum // send sum to c}func main() {    s := []int{2, 8, -9, 4, 0, 99}    c := make(chan int)    go sum(s[len(s)/2:], c)    go sum(s[:len(s)/2], c)    x, y := <-c, <-c // receive from c    fmt.Println(x, y, x+y)}产生以下输出:Sending 1 to chanSending 103 to chan1 103 104在此,x 获得第二个总和,y 获得第一个总和。为什么顺序颠倒了?
查看完整描述

3 回答

?
慕桂英4014372

TA贡献1871条经验 获得超13个赞

类似于goroutine 的执行顺序

如果多次运行,可能会得到不同的结果。当我运行这个时,我得到:


Sending 103 to chan

Sending 1 to chan

103 1 104

如果你希望结果是确定性的。您可以使用两个渠道:


func main() {

    s := []int{2, 8, -9, 4, 0, 99}


    c1 := make(chan int)

    c2 := make(chan int)

    go sum(s[len(s)/2:], c1)

    go sum(s[:len(s)/2], c2)


    x, y := <-c1, <-c2 // receive from c


    fmt.Println(x, y, x+y)

}


查看完整回答
反对 回复 2023-07-31
?
千巷猫影

TA贡献1829条经验 获得超7个赞

goroutine 的执行顺序没有保证。当您启动多个 goroutine 时,它们可能会也可能不会按照您期望的顺序执行,除非它们之间存在显式同步,例如通道或其他同步原语。

在你的例子中,第二个 goroutine 在第一个 goroutine 之前写入通道,因为没有机制来强制两个 goroutine 之间的排序。


查看完整回答
反对 回复 2023-07-31
?
杨__羊羊

TA贡献1943条经验 获得超7个赞

golang规范关于通道的说明:

通道充当先进先出队列。例如,如果一个 Goroutine 在通道上发送值,而第二个 Goroutine 接收它们,则这些值将按照发送的顺序接收。

如果将上述语句与 goroutine 执行的任意顺序结合起来,可能会导致将项目排队到通道中的任意顺序。

查看完整回答
反对 回复 2023-07-31
  • 3 回答
  • 0 关注
  • 113 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信