几天前我开始学习语言.当我试着开始写一些有趣的代码时,我被一种奇怪的行为所困扰.
package main
import "fmt"
func recv(value int) {
if value < 0 {
return
}
fmt.Println(value)
go recv(value-1)
}
func main() {
recv(10)
}
Run Code Online (Sandbox Code Playgroud)
当我运行上面的代码时,只10打印.当我go在打电话之前删除时recv,10要0打印出来.我相信我在这里滥用常规,但我无法理解为什么它以这种方式失败开始.
Dom*_*nef 16
当main函数返回时,Go不会等待任何仍然存在的goroutine完成,而是退出.
recv 在第一次"迭代"之后将返回main,因为main没有更多的事情要做,程序将终止.
这个问题的一个解决方案是有一个信号表明所有工作都已完成,如下所示:
package main
import "fmt"
func recv(value int, ch chan bool) {
if value < 0 {
ch <- true
return
}
fmt.Println(value)
go recv(value - 1, ch)
}
func main() {
ch := make(chan bool)
recv(10, ch)
<-ch
}
Run Code Online (Sandbox Code Playgroud)
这里,recv将在返回之前发送一个布尔值,并将main在通道上等待该消息.
对于程序的逻辑,使用什么类型或特定值无关紧要.bool而且true只是一个简单的例子.如果你想提高效率,使用a chan struct{}而不是a chan bool将节省额外的字节,因为空结构不使用任何内存.
jim*_*imt 10
A sync.Waitgroup是另一种解决方案,专门用于等待任意数量的goroutine运行它们的过程.
package main
import (
"fmt"
"sync"
)
func recv(value int, wg *sync.WaitGroup) {
if value < 0 {
return
}
fmt.Println(value)
wg.Add(1) // Add 1 goroutine to the waitgroup.
go func() {
recv(value-1, wg)
wg.Done() // This goroutine is finished.
}()
}
func main() {
var wg sync.WaitGroup
recv(10, &wg)
// Block until the waitgroup signals
// all goroutines to be finished.
wg.Wait()
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4473 次 |
| 最近记录: |