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
}
...
}
In my case if we run go foo()
it should wait for bar()
to finish and vice versa. What is the best way to do it? Note that they also can be executed independently.
Your requirements cannot be satisfied safely by any concrete design. As prescribed, you say that
foo
andbar
can run in concurrent goroutines, and that if either or both of them have started, the other should wait for them both to finish. That is too weak of a prescription, though; what happens iffoo
starts and then would finish, butbar
hasn't started running yet? What ifbar
never runs at all? Or what ifbar
runs, butfoo
never does?Are you mandating that both
foo
andbar
must start and complete in order for your program to be correct? If so, I can guess as to what you meant to prescribe: You want a barrier that waits for them both to complete before proceeding.(That same example in the Playground)
Note that here, neither
foo
norbar
are mutually aware; only their callers are, in the interest of coordinating the two calls.Your original attempt might lead you down the road of making
foo
andbar
each close over or accept as a parameter async.WaitGroup
, with each function first adding itself to the group and waiting on it before exiting. That way lies madness.If
foo
starts and completes beforebar
has a chance to add itself to theWaitGroup
,foo
will exit beforebar
, even though you could claim they had been running concurrently, or the converse withbar
running beforefoo
can register its active state. Again, since this is a poorly specified aspect of your program, I suggest you instead focus on a higher-level barrier and not on the mutual dependence of these two functions.