我尝试了解未缓冲频道时出现的错误:
“致命错误:所有goroutine都在睡觉-死锁!”
package main
import "fmt"
func main() {
ch := make(chan int)
ch <- 1
gg := <-ch
fmt.Println(gg)
}
在我缓冲频道ch := make(chan int,2)
答案 0 :(得分:1)
通过非缓冲通道发送和检索数据都是阻塞过程。
在您的代码中,您尝试通过通道1
发送数值ch
。由于该操作正在阻塞,因此在当前行执行完成之前,不会执行下面的代码。
在执行语句ch <- 1
的同时,没有运行用于从通道ch
检索数据的进程。因为通道类型是非缓冲通道,所以发送和检索过程需要在完全相同的时间进行。
在下面的示例中,我创建了一个goroutine,该例程包含用于通过通道发送数据的代码,以及主例程中用于从通道检索数据的另一个代码。这将起作用,因为主例程和goroutine进程将分别并发执行。
go func () {
ch <- 1
}()
gg := <-ch
工作场所:https://play.golang.org/p/ceIoVQLItNk
还有一个叫做缓冲通道的东西。使用此功能,即使没有同时运行的用于检索数据的进程,您也可以多次通过通道发送数据。但是有一条规则要遵循:您只能发送n
次,而n
代表缓冲区编号。
示例1:发送2次数据(缓冲区设置为3),然后进行检索:
ch := make(chan int, 3)
ch <- 1
ch <- 1
gg := <-ch
输出:无需恐慌
示例2:发送数据4次(缓冲区设置为3),然后进行检索:
ch := make(chan int, 3)
ch <- 1
ch <- 1
ch <- 1
ch <- 1
gg := <-ch
输出:致命错误:所有goroutine都在睡眠中-死锁!