[CLOSED] - [sync.WaitGroup] - not waiting until everything is done?

Hello!

I’d like to know why, depending on the repetitions, sync.WaitGroup won’t do everything it’s supposed to do.

Here’s an example:

package main

import (
	"fmt"
	"strconv"
	"sync"
)

type person struct {
	name string
}

const amount = 20000

func withoutWaitGroup() {
	var people []person
	
	for i := 0; i < amount; i++ {
		people = append(people, person{name: "a"+strconv.Itoa(i)})	
	}

	fmt.Printf("sequential: length should be %d, got %d.", amount, len(people))	
}

func main() {
	withoutWaitGroup()	
        // it prints -> sequential: length should be 20000, got 20000.
}

Using the same idea, but with sync.WaitGroup instead, it’ll show:

package main

import (
	"fmt"
	"strconv"
	"sync"
)

type person struct {
	name string
}

const amount = 20000

func withWaitGroup() {
	var people []person
	var wg sync.WaitGroup
	
	for i := 0; i < amount; i++ {
		wg.Add(1)
		
		go func(count int) {
			people = append(people, person{name: "a"+strconv.Itoa(count)})
			wg.Done()
		}(i)
	}
	
	wg.Wait()

	fmt.Printf("sync.WaitGroup: length should be %d, got %d.", amount, len(people))
}

func main() {
	withWaitGroup()	
        // it prints -> sync.WaitGroup: length should be 20000, got 513.
}

If I change, from 20000 repetitions, to, say, 1000, it works just fine.

Is there a reason for such behavior? Is it a known bug or am I missing something?

Here’s the code: https://play.golang.org/p/4ZATD_Z2Ui

Run your code with -race. You are concurrently modifying people without synchronization.

1 Like

Makes sense, @calmh. Thanks! It got much slower, but at least got all the results.

Yes. As there’s nothing to do in parallel really, all you’re doing is the same sequential work but in a lot of goroutines and with locking on top.

Yeah, I was just trying out sync.WaitGroup, because I was solving some stuff sequentially or with channels. Thanks again.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.