How to get the number of goroutines associated with a WaitGroup?
Asked Answered
A

2

9

Let’s say I use a WaitGroup to make the main thread of an application wait until all the goroutines I have launched from said main have completed.

Is there a safe, straightforward, way to assess at any point in time how many goroutines associated with said WaitGroup are still running?

Amazonas answered 31/8, 2021 at 8:15 Comment(0)
D
21

The internal state of the WaitGroup is not exposed, and it won't be: https://github.com/golang/go/issues/7202

I don't think we're likely to make this API more complex. I don't see any way to use counter and waiters that is not subject to race conditions, other than simply printing them out. And for that you can maintain your own counts.

You could implement a counter yourself:

type WaitGroupCount struct {
    sync.WaitGroup
    count int64
}

func (wg *WaitGroupCount) Add(delta int) {
    atomic.AddInt64(&wg.count, int64(delta))
    wg.WaitGroup.Add(delta)
}

func (wg *WaitGroupCount) Done() {
    atomic.AddInt64(&wg.count, -1)
    wg.WaitGroup.Done()
}

func (wg *WaitGroupCount) GetCount() int {
    return int(atomic.LoadInt64(&wg.count))
}

// Wait() promoted from the embedded field

However, even if the counter access is synchronized, it will become stale immediately after you read it, since other goroutines may go on and call Add or Done irrespective of what you are doing with the count — unless you synchronize the entire operation that depends on the count. But in that case, you might need a more complex data structure altogether.

Defective answered 31/8, 2021 at 8:45 Comment(1)
Yeah. Golang authors have weird ideas. Being able to read the number is useful especially for debug purposes.Scorpaenid
P
3

Is there a safe, straightforward, way to assess at any point in time how many goroutines associated with said waitgroup are still running?

No, there isn't.

Simply because Go (the language) has no notion of "goroutines associated with [a] waitgroup".

Poundal answered 31/8, 2021 at 8:18 Comment(4)
Alternatively: the number of goroutines “added” to a given waitgroup or being “monitored” using a given waitgroup (using wg.Add(1) and we:Done())Amazonas
@SergeHulne wg.Add(n) doesn't work on goroutines. goroutines have no real identity. wg.Add(n) add n to the internal counter but this need not correspond to a goroutine. Are you not really interested in goroutines but in the current Waitgroup count?Poundal
All right, how do you build a workaround to access the internal counter (a getter), alternatively how do you mimic said counter: will incrementing / decrementing an integer (inside a mutex) for each Add() / Done() pair do the trick?Amazonas
blackgreen's answer is all there is to know. The internals of a WaitGroup are not exposed and you cannot get hold of the. If you want to record what happend to (and thus what state a WaitGroup is in) you have to implement your own. Typically by wrapping a WaitGroup, capturing Adds and Dones and keeping your own counter.Poundal

© 2022 - 2024 — McMap. All rights reserved.