package main
var fooRunning = false
var barRunning = false
func foo() {
fooRunning = true
defer func() { fooRunning = false }()
if barRunning {
// wait for bar() to finish
}
...
}
func bar() {
barRunning = true
defer func() { barRunning = false }()
if fooRunning {
// wait for foo() to finish
}
...
}
在我的情况下,如果我们运行go foo()
,它应该等待bar()
完成,反之亦然。最好的方法是什么?请注意,它们也可以独立执行。
答案 0 :(得分:0)
任何具体设计都无法安全地满足您的要求。按照规定,你说foo
和bar
可以在并发goroutine中运行,如果其中一个或两个都已启动,另一个应该等待它们两个完成。但是,处方太弱了;如果foo
开始然后结束会发生什么,但bar
尚未开始运行?如果bar
根本没有运行怎么办?或者如果bar
运行,但foo
从未执行过,该怎么办?
您是否要求foo
和bar
必须启动并完成以使您的计划正确无误?如果是这样,我可以猜测你的意思是什么:你想要一个等待它们的barrier在继续之前完成。
package main
import (
"fmt"
"sync"
"time"
)
func foo() {
fmt.Println("foo")
}
func bar() {
fmt.Println("bar")
}
func within(wg sync.WaitGroup, f func()) {
wg.Add(1)
go func() {
defer wg.Done()
f()
}()
}
func main() {
var wg sync.WaitGroup
within(wg, foo)
within(wg, bar)
wg.Wait()
fmt.Println("Both foo and bar completed.")
}
(That same example in the Playground)
请注意,此处foo
和bar
都不会相互了解;只有他们的呼叫者才能协调这两个电话。
您的原始尝试可能会引导您将foo
和bar
各自关闭或接受sync.WaitGroup
作为参数,每个函数首先adding itself to the group并且退出前waiting on it。那种方式就是疯狂。
如果foo
在bar
有机会将自己添加到WaitGroup
之前开始并完成,foo
将在bar
之前退出,即使您可以声称它们已同时运行,或者与bar
之前运行的foo
相反,可以注册其活动状态。同样,由于这是您的程序中指定的方面,我建议您专注于更高级别的障碍而不是这两个功能的相互依赖。
答案 1 :(得分:-1)
您可以使用频道!正如我记得生锈的那样,这会给出:
func foo() {
c := make(chan int)
go bar(c)
<-c
}
并在栏中
func bar(c chan int) {
// do stuff here
c <- 0
}