英文:
Testing Goroutine That My Code Does Not Wait For
问题
我有一个并发执行的函数。它的任务是运行一个命令行方法,并在出现错误时记录错误日志。我的主线程不等待这个方法执行完毕,而是乐观地返回。
如何测试我的函数?假设我给它一个cmdStr
,比如{"sleep", "1"}
,它可以工作但不会立即返回,我该如何让我的测试等待这个函数执行完毕?
我希望确保实际运行这个函数的程序不必等待它执行完毕。
func runCmd(cmdStr []string, errChan chan error) {
cmd := exec.Command(cmdStr...)
var out bytes.Buffer
cmd.Stdout = &out
err := cmd.Start()
if err != nil {
errChan <- err
return
}
// 命令成功启动,所以我们的调用者可以继续执行。
errChan <- nil
err = cmd.Wait()
if err != nil {
log.Println(err)
}
}
英文:
I have a function that is executed concurrently. It's task is to run a command line method, logging an error if there is one. My main thread of execution does not wait for this method to finish. It simply returns optimistically.
How do I test my function? Assuming that I give it a cmdStr
, such as {"sleep", "1"}
, that works but doesn't return instantly, how can I get my test to wait for this function to finish?
I want to ensure that the actual program that runs this does not have to wait for it to finish.
func runCmd(cmdStr []string, errChan chan error) {
cmd := exec.Command(cmdStr...)
var out bytes.Buffer
cmd.Stdout = &out
err := cmd.Start()
if err != nil {
errChan <- err
return
}
// Command started successfully, so our caller can continue.
errChan <- nil
err = cmd.Wait()
if err != nil {
log.Println(err)
}
}
答案1
得分: 1
使用等待组(wait group)
wg := sync.WaitGroup{}
errc := make(chan error)
wg.Add(1)
go func() {
runCmd([]string{"sleep", "1"}, errc)
wg.Done()
}()
err := <-errc
if err != nil {
// 处理错误
}
wg.Wait()
请注意,以上是给出的代码的翻译版本。如果您有任何问题或需要进一步的帮助,请随时告诉我。
英文:
Use a wait group
wg := sync.WaitGroup{}
errc := make(chan error)
wg.Add(1)
go func() {
runCmd([]string{"sleep", 1}, errc)
wg.Done()
}()
err <- errc
if err != nil {
// handle error
}
wg.Wait()
答案2
得分: 0
最简单的方法是在main.main()
的最后一条语句中添加select{}
。但是这样main()
将永远不会返回,你需要显式地终止进程。
另外一种更温和的方法是使用runtime.Gosched()
等待其他goroutine,但它不能提供如此强的保证。
而规范的做法是:
wg := sync.WaitGroup
...
wg.Add(1)
go runCmd(...)
...
wg.Wait()
英文:
Simplest method to aware all goroutings done is to add select{}
as last main.main()
statement. But main()
will never return this way and you should kill process explicitly.
It's also more gentle runtime.Goshed()
to wait for others, but it can't provide such a strong guarantee.
And the canonical way would be
wg := sync.WaitGroup
...
wg.Add(1)
go runCmd(...)
...
wg.Wait()
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论