Skip to content

sync.WaitGroup panic trouble me #39013

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
littlejiancc opened this issue May 12, 2020 · 1 comment
Closed

sync.WaitGroup panic trouble me #39013

littlejiancc opened this issue May 12, 2020 · 1 comment

Comments

@littlejiancc
Copy link

What version of Go are you using (go version)?

$ go version
go version go1.14.1 windows/amd64

What did you do?

When I study sync.WaitGroup. And this problem has troubled me for a long time!
This is my code:

package main

import "sync"

func main() {
	for i := 0; i < 1e6; i++ {
		var wg sync.WaitGroup
		wg.Add(1)
		go func() {
			wg.Add(1)
			wg.Done()
		}()
		go func() {
			wg.Wait()
		}()
		wg.Done()
	}
}

As we know,Add called concurrently with Wait will panic:

GOROOT=C:\Go #gosetup
GOPATH=D:\go #gosetup
C:\Go\bin\go.exe build -o C:\Users\AH\AppData\Local\Temp\___go_build_awesomeProject.exe awesomeProject #gosetup
C:\Users\AH\AppData\Local\Temp\___go_build_awesomeProject.exe #gosetup
panic: sync: WaitGroup misuse: Add called concurrently with Wait

goroutine 150022 [running]:
sync.(*WaitGroup).Add(0xc00053bda0, 0x1)
        C:/Go/src/sync/waitgroup.go:77 +0x124
main.main.func1(0xc00053bda0)
        D:/go/src/awesomeProject/main.go:10 +0x3b
created by main.main
        D:/go/src/awesomeProject/main.go:9 +0x82

However!
When the code like this,it's well done!

package main

import "sync"

func main() {
	for i := 0; i < 1e6; i++ {
		var wg sync.WaitGroup
		//wg.Add(1)
		go func() {
			wg.Add(1)
			wg.Done()
		}()
		go func() {
			wg.Wait()
		}()
	//	wg.Done()
	}
}

I think it also has chance Add called concurrently with Wait .
So why it always well done?

@ALTree
Copy link
Member

ALTree commented May 12, 2020

Both programs are racy and thus invalid; but I think that the first one triggers more easily the check that prints the WaitGroup is reused before previous Wait has returned error.

Run them with the race detector enabled using go run -race program.go and you'll see this data race reported in both cases:

==================
WARNING: DATA RACE
Write at 0x00c000094298 by goroutine 72:
  internal/race.Write()
      /usr/local/go/src/internal/race/race.go:41 +0x114
  sync.(*WaitGroup).Wait()
      /usr/local/go/src/sync/waitgroup.go:128 +0x115
  main.main.func2()
      /home/alberto/test.go:14 +0x38

Previous read at 0x00c000094298 by goroutine 7:
  internal/race.Read()
      /usr/local/go/src/internal/race/race.go:37 +0x1e8
  sync.(*WaitGroup).Add()
      /usr/local/go/src/sync/waitgroup.go:71 +0x1fb
  main.main.func1()
      /home/alberto/test.go:10 +0x41

Goroutine 72 (running) created at:
  main.main()
      /home/alberto/test.go:13 +0xd0

Goroutine 7 (finished) created at:
  main.main()
      /home/alberto/test.go:9 +0xae
==================

So the second program is invalid too. Closing here, since we only use the issue tracker for Go bugs, not for asking questions.

@ALTree ALTree closed this as completed May 12, 2020
@golang golang locked and limited conversation to collaborators May 12, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants