Overview
sync package 内にある semaphore を使って Go のアプリケーション側で goroutine の起動数を排他制御します。
Go の並行処理の起動数を制御するのは
使い方
https://pkg.go.dev/golang.org/x/sync/semaphore#section-documentation のサンプルにある実装方法に準拠するだけでOKです。
// goroutine の上限を指定する。 var maxConcurrentNum int64 = 20 sem := semaphore.NewWeighted(maxConcurrentNum) ctx := context.Backgrdound() for i := range 20 { if err := sem.Acquire(ctx, 1); err != nil { return err } go func(ctx context.Context) { defer func() { sem.Release(1) if err := recover(); err != nil { fmt.Errorf("err: %v\n", err) } }() // do concurrent proccess without cancel context cctx := context.WithoutCancel(ctx) }(ctx) } // 最期に全部の worker pool を取得して、意図しないプロセスがゾンビとして残らないようにする。 if err := sem.Acquire(ctx, maxConcurrentNum); err != nil { return err }
注意点として semaphore を Acquire する(P操作)ときに、 TryAcquire
というメソッドも利用できますが、これは「利用可能か」の結果を返すだけのメソッドなので、Godoc の使い方の通り Acquire
メソッドを使いましょう。こちらは semaphore に利用可能なプロセスがあるか、が充填されるまで処理を Blocking してくれます。