首页 文章

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

提问于
浏览
0

我正在尝试使用go stream,我有一些“愚蠢”的问题 .

我已经完成了一个带有字节限制范围的原始流示例,这里是工作代码,这是我的问题 .

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)
}

谢谢你的帮助!抱歉原始问题 .

2 回答

  • 0

    因为通道操作符 <- 只从通道中获取1个元素 . 如果你想将它们打印在一起试试: fmt.Println("%v%v", <-c, <-c)"

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

    这同样适用于所有渠道 - 未受影响的渠道在第一次元素撰写时被封锁 . 直到一些goroutine从 Channels 读取 .

    因为没有goroutine可读,所以永远地写一个锁 . 您可以在开始阅读goroutine之前解决它 .

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

    这种方式不会被锁定,而是开始传输物品 .

  • 1

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

    答:因为你使用Println()方法 . 如果你想在一行上使用Print()

    2我尝试使用此代码来了解它是如何工作的,我已经删除了字节rande并且我遇到了死锁错误 . 为什么会这样?

    就代码所示,您永远不会为您创建的 Channels 启动并发读取器 . 因为它是无缓冲的,所以对它的任何写入都会阻塞,直到有人从某个地方读取另一端 .

相关问题