一个基本的 Golang 流(通道)死锁



我正在尝试使用 go 流,我有几个"愚蠢"的问题。

我已经用字节限制范围做了一个原始流示例,这是工作代码,这是我的问题。

1 - 为什么此代码在新行显示 1 和 2?为什么它不显示 12 在那个?字节的第一个和平是否从字节限制流中删除?(但是当我们已经推送了 1 个数字时,我们如何将 2 个数字推送到流中?我只是听不懂

package main
import "fmt"
func main() {
    ch := make(chan int, 2)
    ch <- 1
    ch <- 2
    fmt.Println(<-ch)
    fmt.Println(<-ch)
}
It shows:
1
2

2 问题 - 我试图使用此代码以了解它的工作原理,并且我删除了字节范围,并且出现了死锁错误。为什么会这样?谢谢!

fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan send]:
main.main()
    /tmp/sandbox557775903/main.go:7 +0x60

死锁错误代码:

package main
import "fmt"
func main() {
    ch := make(chan int)
    ch <- 1
    ch <- 2
    fmt.Println(<-ch)
    fmt.Println(<-ch)
}

感谢您的任何帮助!很抱歉原始问题。

因为通道运算符<-只从通道中获取 1 个元素。如果您希望将它们打印在一起,请尝试:fmt.Println("%v%v", <-c, <-c)"

通道创建中的最后一个数字make(chan int, 2)表示通道缓冲区 - 其存储项目的容量。因此,您可以轻松地将 2 个项目推送到频道。但是,如果您尝试再推送一个项目会发生什么?该操作将被阻止,因为在另一个 goroutine 从通道读取和可用空间之前没有空间。

这同样适用于所有通道 - 未受冲击的通道在第一次元素写入时被阻止。直到一些goroutine从通道中读取。

因为没有goroutine可以阅读,所以写一个永远锁定。你可以解决它之前开始一个阅读程序。

 c := make(chan int)
go func () {
    fmt.Println(<-c)
    fmt.Println(<-c)
}()
ch <- 1
ch <- 2

这种方式不会被锁定,而是开始传输项目。

1 - 为什么此代码在新行显示 1 和 2?

答:因为你使用 Println() 方法。如果您希望它们在一行上使用 Print()

2 我尝试使用此代码以了解其工作原理,并且删除了字节兰德,并且出现了死锁错误。为什么会这样?

就代码所示,您永远不会为您创建的通道启动并发读取器。因为它是未缓冲的,所以对它的任何写入都将阻塞,直到某人从另一端读取。

最新更新