简体   繁体   English

基本的Golang流(通道)死锁

[英]A basic Golang stream(channel) deadlock

I am trying to work with go streams and I have a few "stupid" question. 我正在尝试使用go stream,但有几个“愚蠢”的问题。

I have done a primitive stream example with the byte limit range and here is the working code and here are my questions. 我已经用字节限制范围做了一个原始的流示例,这是工作代码,这是我的问题。

1 - why this code shows 1 and 2 at the new line? 1-为什么此代码在新行显示1和2? Why doesn't it show 12 at the one? 为什么它没有一次显示12? Does the first peace of bytes removed from the byte-limited stream? 是否从字节限制的流中删除了字节的第一和平? (But how we can push the 2 number into the stream when we have already pushed the 1 number?) I just can't understand it (但是,当我们已经将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 question - I have tried to play with this code to understand how it works and I have removed the byte range and I have got the deadlock error. 2个问题-我尝试使用此代码来了解其工作原理,并且删除了字节范围,并遇到了死锁错误。 Why does it happen? 为什么会发生? Thanks! 谢谢!

fatal error: all goroutines are asleep - deadlock!

goroutine 1 [chan send]:
main.main()
    /tmp/sandbox557775903/main.go:7 +0x60

The deadlock error code: 死锁错误代码:

package main

import "fmt"

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

Thanks for any help! 谢谢你的帮助! Sorry for the primitive questions. 对不起原始问题。

Because channel operator <- takes only 1 element from the channel. 因为通道运算符<-仅占用通道中的1个元素。 If you want them printed together try: fmt.Println("%v%v", <-c, <-c)" 如果希望它们一起打印,请尝试: fmt.Println("%v%v", <-c, <-c)"

Last number in channel creation make(chan int, 2) means channel buffer - its capacity to store items. 通道创建中的最后一个数字make(chan int, 2)表示通道缓冲区-它存储项目的能力。 So you can easily push 2 items to channel. 因此,您可以轻松地将2个项目推送到频道。 But what happens if you try to push one more item? 但是,如果您尝试再推一件商品,会发生什么? The operation would be blocked because there's no space until another goroutine will read from the channel and free space. 该操作将被阻止,因为在从通道读取另一个goroutine并释放空间之前,没有空间。

The same applies to all channels - unbuffeted ones get blocked at first element writing. 同样适用于所有通道-未缓冲的通道会在首次写入元素时被阻塞。 Until some goroutine reads from the channel. 直到从该通道读取某些goroutine。

Because there's no goroutine to read, writing one locks forever. 因为没有要读取的goroutine,所以要永远写一个锁。 You may solve it starting a reading goroutine before. 您可以在开始阅读goroutine之前解决该问题。

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

This way would not get locked but start transmitting items. 这种方式不会被锁定,而是开始传输项目。

1 - why this code shows 1 and 2 at the new line ? 1-为什么此代码在新行显示1和2?

Answer: because you use Println() method. 答:因为您使用Println()方法。 If you want them on one line use Print() 如果您希望将它们放在一行上,请使用Print()

2 I have tried to play with this code to understand how it works and I have removed the byte rande and I have got the deadlock error. 2我尝试使用此代码来了解其工作原理,并且删除了字节字数,并出现了死锁错误。 Why it happens? 为什么会发生?

As far as the code shows, you are never firing up a concurrent reader for the channel you create. 就代码所示而言,您永远不会为您创建的频道启动并发阅读器。 Because it is unbuffered, any writes to it, will block until someone, somewhere reads from the other end. 因为它是无缓冲的,所以对它的任何写操作都将阻塞,直到有人从另一端读取。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM