如何等待所有的goroutines完成,而不使用time.Sleep?
此代码select与被调用的可执行文件相同的文件夹中的所有xml文件,并将asynchronous处理应用于callback方法中的每个结果(在下面的示例中,只是打印出文件的名称)。
我如何避免使用睡眠方法来防止主要方法退出? 我有问题缠绕我的头(我假设这是需要的,同步结果),所以任何帮助表示赞赏!
package main import ( "fmt" "io/ioutil" "path" "path/filepath" "os" "runtime" "time" ) func eachFile(extension string, callback func(file string)) { exeDir := filepath.Dir(os.Args[0]) files, _ := ioutil.ReadDir(exeDir) for _, f := range files { fileName := f.Name() if extension == path.Ext(fileName) { go callback(fileName) } } } func main() { maxProcs := runtime.NumCPU() runtime.GOMAXPROCS(maxProcs) eachFile(".xml", func(fileName string) { // Custom logic goes in here fmt.Println(fileName) }) // This is what i want to get rid of time.Sleep(100 * time.Millisecond) }
你可以使用sync.WaitGroup 。 引用链接的例子:
package main import ( "net/http" "sync" ) func main() { var wg sync.WaitGroup var urls = []string{ "http://www.golang.org/", "http://www.google.com/", "http://www.somestupidname.com/", } for _, url := range urls { // Increment the WaitGroup counter. wg.Add(1) // Launch a goroutine to fetch the URL. go func(url string) { // Decrement the counter when the goroutine completes. defer wg.Done() // Fetch the URL. http.Get(url) }(url) } // Wait for all HTTP fetches to complete. wg.Wait() }
WaitGroups绝对是这样做的标准方式。 但是,为了完整起见,这里是WaitGroups推出之前常用的解决scheme。 基本的想法是使用一个通道来说“我已经完成了”,并且让主程序等待,直到每个产生的程序报告完成为止。
func main() { c := make(chan struct{}) // We don't need any data to be passed, so use an empty struct for i := 0; i < 100; i++ { go func() { doSomething() c <- struct{}{} // signal that the routine has completed }() } // Since we spawned 100 routines, receive 100 messages. for i := 0; i < 100; i++ { <- c } }