go - 一个基本的 Golang 流( channel )死锁

标签 go stream deadlock bytestream

我正在尝试使用 go streams,我有几个“愚蠢”的问题。

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

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

感谢您的帮助!很抱歉提出原始问题。

最佳答案

因为 channel 运营商<-仅从 channel 中获取 1 个元素。如果你想让它们一起打印,试试:fmt.Println("%v%v", <-c, <-c)"

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

这同样适用于所有 channel - 未缓冲的 channel 在第一个元素写入时被阻塞。直到一些 goroutine 从 channel 读取。

因为没有goroutine可以读,永远写一个锁。你可以解决它之前启动一个阅读协程。

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

这种方式不会被锁定,而是开始传送元素。

关于go - 一个基本的 Golang 流( channel )死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46645981/

相关文章:

javascript - 如何在 JavaScript block 的 HTML 模板中禁用转义 URL/字符串

google-app-engine - 应用引擎推送任务在测试中总是返回 404

node.js - 如何将背压应用于 Node 流?

java - 读取和写入多个 HashMap

javascript - Node 读流: when does the streaming happen?

multithreading - 多线程程序在 _multiple_ CPU 上变得无响应,但在单个 CPU 上正常(更新 ListView 时)

Java多线程程序(生产者和消费者)挂起..?

macos - go 在 Mac OS X 中尝试执行 go install 时失败

json.Marshal(struct) 返回 "{}"

c# - 从工作线程调用 UI 线程时出现死锁