一个基本的 Golang 流(通道)死锁
A basic Golang stream(channel) deadlock
我正在尝试使用 go 流,但我有几个 "stupid" 问题。
我已经完成了一个带有字节限制范围的原始流示例,这是工作代码,这是我的问题。
1 - 为什么此代码在新行显示 1 和 2?为什么它不显示12?是否从字节限制流中删除了第一个和平字节? (但是我们已经push了1号了,怎么把2号push到stream里呢?)我就是看不懂
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 - why this code shows 1 and 2 at the new line ?
答:因为你使用了Println()方法。如果你想让它们在一行上使用 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. Why it happens?
就代码显示而言,您永远不会为您创建的频道启动并发 reader。因为它是无缓冲的,所以对它的任何写入都会阻塞,直到有人在某处从另一端读取。
因为通道运算符 <-
仅从通道中获取 1 个元素。如果你想让它们一起打印,试试:fmt.Println("%v%v", <-c, <-c)"
通道创建中的最后一个数字make(chan int, 2)
表示通道缓冲区 - 其存储项目的容量。所以你可以轻松地将 2 个项目推送到频道。但是,如果您尝试再推送一项,会发生什么情况?该操作将被阻止,因为没有 space,直到另一个 goroutine 从通道读取并释放 space。
这同样适用于所有通道 - 未缓冲的通道在第一个元素写入时被阻塞。直到一些 goroutine 从通道读取。
因为没有goroutine可以读,永远写一个锁。你可以解决它之前启动一个阅读协程。
c := make(chan int)
go func () {
fmt.Println(<-c)
fmt.Println(<-c)
}()
ch <- 1
ch <- 2
这种方式不会被锁定,而是开始传送物品。
我正在尝试使用 go 流,但我有几个 "stupid" 问题。
我已经完成了一个带有字节限制范围的原始流示例,这是工作代码,这是我的问题。
1 - 为什么此代码在新行显示 1 和 2?为什么它不显示12?是否从字节限制流中删除了第一个和平字节? (但是我们已经push了1号了,怎么把2号push到stream里呢?)我就是看不懂
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 - why this code shows 1 and 2 at the new line ?
答:因为你使用了Println()方法。如果你想让它们在一行上使用 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. Why it happens?
就代码显示而言,您永远不会为您创建的频道启动并发 reader。因为它是无缓冲的,所以对它的任何写入都会阻塞,直到有人在某处从另一端读取。
因为通道运算符 <-
仅从通道中获取 1 个元素。如果你想让它们一起打印,试试:fmt.Println("%v%v", <-c, <-c)"
通道创建中的最后一个数字make(chan int, 2)
表示通道缓冲区 - 其存储项目的容量。所以你可以轻松地将 2 个项目推送到频道。但是,如果您尝试再推送一项,会发生什么情况?该操作将被阻止,因为没有 space,直到另一个 goroutine 从通道读取并释放 space。
这同样适用于所有通道 - 未缓冲的通道在第一个元素写入时被阻塞。直到一些 goroutine 从通道读取。
因为没有goroutine可以读,永远写一个锁。你可以解决它之前启动一个阅读协程。
c := make(chan int)
go func () {
fmt.Println(<-c)
fmt.Println(<-c)
}()
ch <- 1
ch <- 2
这种方式不会被锁定,而是开始传送物品。