はじめに
昔はsyncパッケージを使う必要があり、若干分かりづらいコードになってましたが、
golang.org/x/sync/ で実装すると分かりやすく改善されてたのでサンプルコードをおいてみます。
並列数は3に制限して実行するコードになってます。
syncパッケージのコード
package main import ( "fmt" "sync" "time" ) func main() { num := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} wg := &sync.WaitGroup{} semaphore := make(chan struct{}, 3) for _, v := range num { wg.Add(1) semaphore <- struct{}{} go func(v int) { defer func() { <-semaphore defer wg.Done() }() Hoge(v) }(v) } wg.Wait() } func Hoge(i int) { fmt.Printf("start %v\n", i) time.Sleep(3 * time.Second) fmt.Printf("stop %v\n", i) }
golang.org/x/sync/ のコード
package main import ( "context" "fmt" "log" "time" "golang.org/x/sync/errgroup" "golang.org/x/sync/semaphore" ) func main() { num := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} sem := semaphore.NewWeighted(3) eg := errgroup.Group{} for _, v := range num { if err := sem.Acquire(context.Background(), 1); err != nil { fmt.Printf("failed to acquire semaphore: %v\n", err) break } v := v eg.Go(func() error { defer sem.Release(1) Hoge(v) return nil }) } if err := eg.Wait(); err != nil { log.Fatal(err) } } func Hoge(i int) { fmt.Printf("start %v\n", i) time.Sleep(3 * time.Second) fmt.Printf("stop %v\n", i) }