gpt4 book ai didi

去教程: Channels and Buffered Channels

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

为什么当第二个值通过另一个 go routine 发送并且没有收到发送的第一个值时, channel c 没有缓冲?

package main
import "fmt"

func sum(s []int, c chan int) {
sum := 0
for _, v := range s {
sum += v
}
c <- sum // send sum to c
}

func main() {
s := []int{7, 2, 8, -9, 4, 0}
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)
}

我期待的是一个错误-

fatal error: all goroutines are asleep - deadlock!

当缓冲区已满时出现阻塞时会发生这种情况。由于 channel c 的大小为 1,因此发送第二个值应该会出现上述错误。

上面的代码发生了什么?

最佳答案

仅仅因为写入不能立即成功,只要有其他 goroutine 可以运行,您就不会得到“死锁”错误。

让我们想象一个调度模型,其中 go 函数立即启动 goroutine 并在让步给其他人之前尽可能多地向前推进。那么这将发生:

  1. 程序将为列表的前半部分调用sum(),计算和,并尝试将其写入 channel ,但由于没有监听器,它会阻塞。
  2. 程序将为列表的后半部分调用sum(),计算总和,并尝试将其写入 channel ,但由于没有监听器,它会阻塞。
  3. main() 将尝试从 channel 中读取数据,唤醒之前的 goroutine 之一,并从中获取值。
  4. main() 将尝试从 channel 读取数据,唤醒其他阻塞的 goroutine,并从中获取值。
  5. 没有人再阻塞 channel 输入或输出,所有 goroutine(包括 main())都可以运行完成。

如果你假装 go 只是在后台安排一些事情并继续运行主 goroutine,你可以做同样的练习。重要的是,只要在同一个 channel 上有成对的读写,两者都会继续。

关于去教程: Channels and Buffered Channels,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51613955/

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