我有两组代码-读取具有随机文本行的文件,并将每一行加载到一个通道。我不明白为什么会返回错误。但是另一个没有。案例1返回“致命错误:所有goroutine都在睡着-死锁!”但是案例号有效。
func main(){
file, err := os.Open("/Users/sample/Downloads/wordlist")
if err != nil {
log.Fatal(err)
}
lines := make (chan string)
scanner := bufio.NewScanner(file)
for scanner.Scan() {
lines <- scanner.Text()
}
close(lines)
for line := range (lines) {
fmt.Println(line)
}
}
func main(){
file, err := os.Open("/Users/sample/Downloads/wordlist")
if err != nil {
log.Fatal(err)
}
lines := make (chan string)
go func() {
scanner := bufio.NewScanner(file)
for scanner.Scan() {
lines <- scanner.Text()
}
close(lines)
}()
for line := range (lines) {
fmt.Println(line)
}
}
答案 0 :(得分:1)
发送方阻塞,直到接收方在非缓冲通道中接收到该值为止。
在无缓冲的通道中,只有在必须有一些等待接收数据的接收器时,才会写入该通道。
例如:
queue := make(chan string)
queue <- "one" /* Here main function which is also a goroutine is blocked, because
there is no goroutine to receive the channel value, hence the deadlock*/
close(queue)
for elem := range queue {
fmt.Println(elem)
}
这将导致死锁,而这正是您的 Case#1 代码中发生的情况。
现在,如果我们还有其他例行检查
queue := make(chan string)
go func() {
queue <- "one"
close(queue)
}()
for elem := range queue {
fmt.Println(elem)
}
这将起作用,因为main go例程在写数据到未缓冲的通道之前正在等待数据被消耗。
这确实是在您的第2种情况
中发生的因此,简而言之,只有在有一些例程正在等待从通道读取时,才会发生对未缓冲通道的写入,否则写入操作将永远被阻塞并导致死锁。