【发布时间】:2015-07-05 17:47:33
【问题描述】:
我阅读了Twelve Go Best Practices 并在第 30 页遇到了有趣的例子。
func sendMsg(msg, addr string) error {
conn, err := net.Dial("tcp", addr)
if err != nil {
return err
}
defer conn.Close()
_, err = fmt.Fprint(conn, msg)
return err
}
func broadcastMsg(msg string, addrs []string) error {
errc := make(chan error)
for _, addr := range addrs {
go func(addr string) {
errc <- sendMsg(msg, addr)
fmt.Println("done")
}(addr)
}
for _ = range addrs {
if err := <-errc; err != nil {
return err
}
}
return nil
}
func main() {
addr := []string{"localhost:8080", "http://google.com"}
err := broadcastMsg("hi", addr)
time.Sleep(time.Second)
if err != nil {
fmt.Println(err)
return
}
fmt.Println("everything went fine")
}
程序员提到的,发生在上面的代码中:
the goroutine is blocked on the chan write
the goroutine holds a reference to the chan
the chan will never be garbage collected
为什么goroutine在这里被阻塞了?主线程被阻塞,直到它接收到来自 goroutine 的数据。在它继续for循环之后。不是吗?
为什么 errc chan 永远不会被垃圾回收?因为我没有关闭通道,goroutine完成后?
【问题讨论】: