Open1

goroutine処理のエラー

arainuarainu

参考:Goドキュメント|sync.WaitGroup
https://pkg.go.dev/sync#WaitGroup.Add

エラー内容:WaitGroupの内部カウンターがマイナス値

panic: sync: negative WaitGroup counter
package main

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

func normal(s string) {
	for i := 0; i < 5; i++ {
		time.Sleep(100 * time.Millisecond)
		fmt.Println(s)
	}
}

func goroutine(s string, wg *sync.WaitGroup) {
	for i := 0; i < 5; i++ {
		time.Sleep(100 * time.Millisecond)
		fmt.Println(s)
		wg.Done() // ループ処理内で呼び出されている
	}
}

func main() {
	var wg sync.WaitGroup
	wg.Add(1) // goroutineは1つ
	go goroutine("Goroutine!", &wg)
	normal("Go!")
	wg.Wait()
}

原因

  • Add()とDone()の回数不一致

Add(int)でカウンターをインクリメント
Done()でカウンターをデクリメント

// 適切なコード
package main

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

func normal(s string) {
	for i := 0; i < 5; i++ {
		time.Sleep(100 * time.Millisecond)
		fmt.Println(s)
	}
}

func goroutine(s string, wg *sync.WaitGroup) {
	for i := 0; i < 5; i++ {
		time.Sleep(100 * time.Millisecond)
		fmt.Println(s)
	}
	wg.Done()
}

func main() {
	var wg sync.WaitGroup
	wg.Add(1)
	go goroutine("Goroutine!", &wg)
	normal("Go!")
	wg.Wait()
}
fatal error: all goroutines are asleep - deadlock!
package main

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

func normal(s string) {
	for i := 0; i < 5; i++ {
		time.Sleep(100 * time.Millisecond)
		fmt.Println(s)
	}
}

func goroutine(s string, wg *sync.WaitGroup) {
	for i := 0; i < 5; i++ {
		time.Sleep(100 * time.Millisecond)
		fmt.Println(s)
	}
	// wg.Done()
}

func main() {
	var wg sync.WaitGroup
	wg.Add(1)
	go goroutine("Goroutine!", &wg)
	normal("Go!")
	wg.Wait()
}

原因

  • Done()の記述忘れ

ver1.25でのアップデート