此代码选择同一文件夹中的所有xml文件作为被调用的可执行文件,并在回调方法中对每个结果异步应用处理(在下面的示例中,仅打印出文件名)。
如何避免使用sleep方法来阻止main方法退出?我有问题 Package 我的头周围的渠道(我认为这是什么,同步结果),所以任何帮助是赞赏!
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)
}
5条答案
按热度按时间3yhwsihp1#
您可以使用sync.WaitGroup。引用链接的示例:
falq053o2#
WaitGroups绝对是做这件事的标准方法。不过,为了完整起见,下面是在引入WaitGroups之前常用的解决方案。其基本思想是使用一个通道来表示“我完成了”,并让主goroutine等待,直到每个派生的例程都报告了它的完成。
iugsix8n3#
同步。WaitGroup可以在此为您提供帮助。
vwoqyblh4#
虽然
sync.waitGroup
(wg)是规范的前进方向,但它确实要求您在wg.Wait
之前至少执行一些wg.Add
调用,以便完成所有调用。这对于像web crawler这样简单的东西来说可能不可行,因为您事先不知道递归调用的数量,并且需要一段时间来检索驱动wg.Add
调用的数据。毕竟,在知道第一批子页面的大小之前,您需要加载和解析第一个页面。我写了一个使用通道的解决方案,在我的解决方案Tour of Go - web crawler练习中避免了
waitGroup
。每次启动一个或多个go-routines时,您将数字发送到children
通道。每次一个go例程即将完成时,您就向done
通道发送一个1
。当孩子的总和等于完成的总和时,我们就完成了。我唯一关心的是
results
通道的硬编码大小,但这是(当前)Go的限制。Full source code for the solution
68bkxrlz5#
下面是一个使用WaitGroup的解决方案。
首先,定义2个实用程序方法:
然后,替换
callback
的调用:通过调用你的工具函数:
最后一步,将这一行添加到
main
的末尾,而不是sleep
。这将确保主线程正在等待所有例程完成,然后程序才能停止。