这段代码为什么会出现死锁错误

package main import ( "fmt" ) func f1(in chan int) { fmt.Println(<-in) } func main() { out := make(chan int) out <- 2 go f1(out) } 顺便问一下有什么适合初学者的书籍或者其他资料吗,现在我在看 https://github.com/Unknwon/the-way-to-go_ZH_CN 这本书
已邀请:

Ky

赞同来自: goScepter _Is2 wizard

out := make(chan int) 是无缓冲的,你往里写值,肯定出错的
你需要把这两行 上下互换
out <- 2
go f1(out)

xkey - go

赞同来自: _Is2 goScepter

使用golang的channel记住一个规则,先有消费者,才能有生产者,你的代码顺序明显是先生产后消费,记住这个,channel就不会用错

HikoQiu

赞同来自: _Is2

chan 有两种,无缓冲和有缓冲。

# 1. 无缓冲

无缓冲 chan 的生产消费原则必须符合 CSP(Communication Sequential Processing )。
人话就是:
i. 通过 Send / Receive 实现通信;
ii. 保证收发**同时**成功。

*注意:收发同时成功。*

# 2. 有缓冲

有缓冲则没有无缓冲那样的条件限制,只是一个加锁队列实现的收发。

==

回答你的问题:

你的例子是一个无缓冲 chan,需要符合 CSP 收发同时发生。而你的代码中程序顺序执行,先往 chan 写,再起一个 goroutine 消费。

这很明显没办法达到收发同时进行,所以换下顺序就可以了。

pathbox - https://pathbox.github.io/

赞同来自: _Is2

CSP 的一个原则是 如果接受者(消费者)还没有做好接受消息的准备,那么发送者(生产者)是不能发送消息的。

然后,就像二楼所说的。 Go 在编译阶段识别到了你的代码不符合这种情况,给予报错

tpkeeper - Software Engineer. Gopher. [ tpkeeper.me@gmail.com ]

说阻塞更容易理解,初学推荐《go in action》

要回复问题请先登录注册