Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the method set of `sync.WaitGroup`?

Tags:

go

I have this simple program below

package main

import (
    "fmt"
    "sync"
    "time"
)

var wg sync.WaitGroup

func main() {
    wg.Add(1)

    go func() {
        fmt.Println("starting...")
        time.Sleep(1 * time.Second)
        fmt.Println("done....")
        wg.Done()
    } ()

    wg.Wait()

}

Notice that I use var wg sync.WaitGroup as a value, not a pointer. But the page for the sync package specifies that the Add, Done and Wait function take a *sync.WaitGroup.

Why/How does this work?

like image 848
Jerry Saravia Avatar asked Feb 27 '17 04:02

Jerry Saravia


People also ask

What is sync WaitGroup in Golang?

A WaitGroup waits for a collection of goroutines to finish. The main goroutine calls Add to set the number of goroutines to wait for. Then each of the goroutines runs and calls Done when finished. At the same time, Wait can be used to block until all goroutines have finished.

What is the use of WaitGroup?

A common usage of WaitGroup is to block the main function because we know that the main function itself is also a GoRoutine. You need to import the sync package before you can use WaitGroup.

What is sync once in Golang?

Sync Package To The Rescue The right way to implement a singleton pattern in Go is to use the sync package's Once.Do() function. This function makes sure that your specified code is executed only once and never more than once. The way to use the Once.Do() function is as below.

What is waitgroup in Java?

WaitGroup is actually a type of counter which blocks the execution of function (or might say A goroutine) until its internal counter become 0. How It Works ? WaitGroup exports 3 methods.

How do you stop a waitgroup from blocking a group?

In the code above, we are first using the add function which tells the waitgroup how many goroutines to block for. Then we simply pass the group as a pointer to a goroutine. When the work is done by the goroutine we call the Done method that tells the waitgroup to stop blocking.

Why do I get (&WG) instead of (&X) when using waitgroup?

This is because all the methods of sync.WaitGroup have pointer receivers, so they are all part of the method set of the *sync.WaitGroup type. This is actually a shorthand for (&wg).Add (1), (&wg).Done () etc. If x is addressable and &x 's method set contains m, x.m () is shorthand for (&x).m ().

How to use waitgroup with goroutine?

Waitgroup is a blocking mechanism that blocks when none of the goroutines which is inside that group has executed. If a goroutine is finished it then unblocks the group. Here is an example illustrating how to use a waitgroup with goroutine. fmt.Println ("Working...") fmt.Println ("Done working!")


2 Answers

The method set of sync.WaitGroup is the empty method set:

wg := sync.WaitGroup{}
fmt.Println(reflect.TypeOf(wg).NumMethod())

Output (try it on the Go Playground):

0

This is because all the methods of sync.WaitGroup have pointer receivers, so they are all part of the method set of the *sync.WaitGroup type.

When you do:

var wg sync.WaitGroup

wg.Add(1)
wg.Done()
// etc.

This is actually a shorthand for (&wg).Add(1), (&wg).Done() etc.

This is in Spec: Calls:

If x is addressable and &x's method set contains m, x.m() is shorthand for (&x).m().

So when you have a value that is addressable (a variable is addressable), you may call any methods that have pointer receiver on non-pointer values, and the compiler will automatically take the address and use that as the receiver value.

See related question:

Calling a method with a pointer receiver by an object instead of a pointer to it?

like image 99
icza Avatar answered Oct 13 '22 02:10

icza


In your case you are modifying a global wg object, if you pass it to a function you have to use pointer because you need to modify the object itself. If you pass by value, inside your function you will be modifying a copy of it, not the object itself.

like image 2
Akavall Avatar answered Oct 13 '22 04:10

Akavall