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

前端 未结 3 1333
[愿得一人]
[愿得一人] 2020-12-11 11:31

I have this simple program below

package main

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

var wg sync.WaitGroup

func main() {
    wg.Add(1)

    go f         


        
相关标签:
3条回答
  • 2020-12-11 12:07

    From the documentation WaitGroup :

    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.

    From your Question

    How does this work?

    So for Add method is set the number of goroutine your called. From your code you have only one :

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

    so it will tells goroutine to wait and print the result. as for wg.Done() this is for telling the one gouroutine has finished to work. and it tells to the add to decrement to -1. You can see the code below How Done method works :

    // Done decrements the WaitGroup counter.
    func (wg *WaitGroup) Done() {
        wg.Add(-1)
    }
    

    and finally for the Wait method this is for blocking goroutine until the WaitGroup counter is zero.

    And another:

    Why ?

    from your code above if you don't use WaitGroup you will not be able to print the result from the goroutine.

    All in all you can read it in the documentation.

    0 讨论(0)
  • 2020-12-11 12:19

    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.

    0 讨论(0)
  • 2020-12-11 12:29

    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?

    0 讨论(0)
提交回复
热议问题