2017-10-09 107 views
0

我想与go流合作,我有几个“愚蠢”的问题。一个基本的Golang流(通道)死锁

我已经做了一个基本的流示例与字节限制范围,这里是工作代码,这里是我的问题。

1 - 为什么此代码在新行显示1和2?为什么它不显示12?从字节限制流中移除字节的第一次平安吗? (?但是,我们如何能够推动2号到流时,我们已经推1号),我只是不明白它

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

由于渠道运营商<-仅占用渠道中的一个元素。如果您想让它们一起打印,请尝试:fmt.Println("%v%v", <-c, <-c)"

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

这同样适用于所有频道 - 在第一次元素写入时,未被忽略的频道会被阻止。直到一些goroutine从频道读取。

因为没有看门的办法,所以永远写一个锁。你可以解决它之前开始阅读goroutine。

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

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

+0

谢谢你的回答!这对我帮助很大 – Velidan

0

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

答案:因为您使用Println()方法。如果你希望他们在一行中使用打印()

2我曾尝试使用此代码玩去了解它是如何工作的,我已删除字节朗德,我已经得到了僵局错误。为什么会发生?

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

+0

谢谢你的回答! – Velidan