0

我正在尝试使用 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)
}

谢谢你的帮助!很抱歉这些原始问题。

4

2 回答 2

1

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

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

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

因为没有 goroutine 可以读取,所以永远写一个锁。您可以在之前启动阅读 goroutine 来解决它。

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

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

于 2017-10-09T18:51:04.070 回答
0

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

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

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

就代码显示而言,您永远不会为您创建的频道启动并发阅读器。因为它是无缓冲的,所以对它的任何写入都会阻塞,直到有人在某处从另一端读取。

于 2017-10-09T12:06:22.493 回答