The proper way to wait for a routine procedure
I want to know how to properly wait for the exit procedure to finish before exiting the program. Reading some of the other answers it seems like bool chan will do the trick as in the playground link
func do_stuff(done chan bool) {
fmt.Println("Doing stuff")
done <- true
}
func main() {
fmt.Println("Main")
done := make(chan bool)
go do_stuff(done)
<-done
//<-done
}
I have two questions:
-
why does everything work?
-
What happens if I uncomment the last line? I have a deadlock error. Is it because the channel is empty and there is no other function to send values to it?
source to share
Why <- done
does it work at all?
- This works because the runtime detects that you are writing something to the pipe somewhere else.
what happens if i uncomment the last line?
- The runtime is smart enough to know that nothing is written there and that these are deadlocks.
Bonus if you are limited on memory, you can use done := make(chan struct{})
and done <- struct{}{}
are struct{}
guaranteed to use 0 memory.
source to share
Listening to a channel <- done
is a blocking operation, so your program will not continue until a true or false is sent, i.e. done <- true
...
Depending on the circumstances, your question may have several different answers.
For example, suppose you want to parallelize a series of function calls that are time consuming.
I would use a package sync
for this
package main
import (
"fmt"
"sync"
"time"
)
func main() {
var wg sync.WaitGroup
for i := 0; i < 10; i++ {
wg.Add(1)
go func() {
longOp()
wg.Done()
}()
}
// will wait until wg.Done is called 10 times
// since we made wg.Add(1) call 10 times
wg.Wait()
}
func longOp() {
time.Sleep(time.Second * 2)
fmt.Println("long op done")
}
source to share