rayimpr
rayimpr

Reputation: 95

what is the proper way to use golang sync.WaitGroup

As mentioned in golang doc, sync is intent for low level library routines.

Other than the Once and WaitGroup types, most are intended for use by low-level library routines. Higher-level synchronization is better done via channels and communication.

I am not quite understanding this statement and I use sync like the example below.
My purpose is just to let main thread wait until all the other threads finish, similar to .join() in c++ thread library.

Questions:
1: Is that proper to use sync like this? Or should I use channel instead of sync?
2: What is the difference between channel and sync?

var wg sync.WaitGroup      // declare the variable globally

func send(a string, b string){
    defer wg.Done()
    // do something
}
func main(){
    for i:=0; i<50; i++ {
         wg.Add(1)              // add delta
         go send("1111", "2222")
    }
    wg.Wait()                  // wait until wg becomes 0
}

Any suggestions are appreciate! Thanks!

Upvotes: 1

Views: 3428

Answers (2)

Satachito
Satachito

Reputation: 5888

I don't know whether it is proper, but code below does the trick without using lower level 'sync'.

package main

func send(a string, b string, c chan bool) {
//  println( a, b )
    c <- true;
}

func
main() {

    c := make( chan bool )

    for i:=0; i<50; i++ {
        go send("1111", "2222", c)
    }

    w := 0
    for _ = range c {
        w += 1
        if w == 50 { break }
    }

}

Upvotes: -1

mylk
mylk

Reputation: 21

This example could help you

var wg sync.WaitGroup
done := make(chan bool)

for _, element := range slice {
    wg.Add(1)
    go func(elem interface{}) {
        wg.Done()
    }(element)
}

go func() {
    wg.Wait()
    done <- true
}()

for {
    select {
    case done:
        fmt.Println("All goroutines completed")
        close(done)
        return
    case time.After(time.Minute * 2):
        fmt.Println("Timeout!")
        return
    }
}

Upvotes: 2

Related Questions