Golang goroutine在使用通道的范围函数时不会运行延迟函数。

huangapple go评论106阅读模式
英文:

Golang goroutine not running defer with function that uses range on channel

问题

一个通道上的范围循环应该在通道关闭时保持函数的开放状态,此时函数/协程应该终止。当函数终止时,延迟函数应该在此之前运行。但是,这似乎不是这种情况,我找不到任何原因。

在http://play.golang.org/p/ADu1MzAe9P上的示例代码按预期生成延迟语句,除了从通道接收的函数。有什么原因会导致这种情况吗?谢谢!

英文:

A range on a channel

for s := range cs {
    fmt.Println("Recieved Cake: ", s)
}

should keep a function open until the channel closes at which point the function/goroutine should terminate. When a function terminates the defer function should run just prior. This doesn't seem to be the case and I can't find any reasons why.

Sample code at http://play.golang.org/p/ADu1MzAe9P produces defer statements as expected except for the function that is recieving from the channel. Any reasons as to why this would be? thanks!

答案1

得分: 5

defer函数没有执行的原因是应用程序到达main函数的末尾,导致整个程序在等待goroutine之前终止。

Go规范中提到:
> 当函数main返回时,程序退出。它不会等待其他(非主)goroutine完成。

由于你的recieveCakeAndPack仍在等待通道关闭(这永远不会发生),它将永远不会在程序终止之前执行defer。

编辑

顺便提一下-在函数中将defer语句放在最后是没有意义的。相反,将它们直接放在要延迟执行的语句之后,例如:

fmt.Println("进入函数")
defer fmt.Println("离开函数")

或者

file, err := os.Open("file.txt")
if err != nil {
    return err
}
defer file.Close()

defer函数/方法调用将按照后进先出的顺序在离开函数时执行。

英文:

The reason why the defer function is not executing is that the application reaches the end of the main function causing the entire program to terminate without waiting for goroutines.

Go Specification says:
> When the function main returns, the program exits. It does not wait for other (non-main) goroutines to complete.

Since your recieveCakeAndPack is still waiting for the channel to close (which never happens) it will never defer before the termination of the program.

Edit

On a side note - putting the defer statements last in a function is not meaningful. Instead put them directly after the statement you want to defer such as:

fmt.Println("Entering function")
defer fmt.Println("Leaving function")

or

file, err := os.Open("file.txt")
if err != nil {
    return err
}
defer file.Close()

The defer function/method calls will be executed when leaving the function in a Last-In-First-Out order.

huangapple
  • 本文由 发表于 2014年4月30日 12:53:44
  • 转载请务必保留本文链接:https://go.coder-hub.com/23379923.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定