mat*_*sta 5 concurrency go garbage goroutine
我想了解这张幻灯片中列出的问题:
http://talks.golang.org/2013/bestpractices.slide#27
在URL死亡时复制代码:
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")
}
Run Code Online (Sandbox Code Playgroud)
评论:
我不确定我理解为什么陈永远不会被收集或者哪个goroutine保持对陈的引用.感谢您的时间!
函数文字表示匿名函数.
Run Code Online (Sandbox Code Playgroud)FunctionLit = "func" Function . func(a, b int, z float64) bool { return a*b < int(z) }函数文字可以分配给变量或直接调用.
Run Code Online (Sandbox Code Playgroud)f := func(x, y int) int { return x + y } func(ch chan int) { ch <- ACK }(replyChan)函数文字是闭包:它们可以引用周围函数中定义的变量.然后,这些变量在周围函数和函数文本之间共享,只要它们可访问,它们就会存在.
send语句在通道上发送值.通道表达式必须是通道类型,通道方向必须允许发送操作,并且要发送的值的类型必须可分配给通道的元素类型.
Run Code Online (Sandbox Code Playgroud)SendStmt = Channel "<-" Expression . Channel = Expression .在通信开始之前评估通道和值表达式.通信阻塞,直到发送可以继续.如果接收器准备就绪,则可以继续在无缓冲信道上发送.如果缓冲区中有空间,则可以继续缓冲通道上的发送.关闭通道上的发送通过导致运行时进行
panic.nil通道上的发送会永久阻止.
只有一个go语句,go func(addr string)它是通道变量的闭包errc.
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
}
Run Code Online (Sandbox Code Playgroud)
从那以后开始了两个goroutines len(addrs) == 2.由于err != nil在第一次接收通道时过早退出errc,只有一个goroutine完成.第二个goroutine在发送(写入)到无缓冲通道时被阻止errc; 它永远不会完成.因此,仍然有一个参考errc,所以它从来没有垃圾收集.当程序退出时,第二个goroutine最终被放弃了.