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?

+3


source to share


2 answers


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.

+5


source


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")
}

      

+5


source







All Articles