セマフォパターン
チャネルセマフォで並行性を制限します。
「セマフォパターン」はCoddyKit上の無料Go Academyレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはGo Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Go Academyコースには全4レッスンが含まれています。
セマフォとは
セマフォは、1つの操作を同時に実行できるgoroutineの数を制限します。これにより、リソースの枯渇(データベース接続を開きすぎる、外部HTTPリクエストを送信しすぎるなど)を防ぎます。
セマフォとしてのバッファ付きチャネル
容量Nのバッファ付きチャネルは、カウント型セマフォとして機能します。チャネルに送信すると取得になり、チャネルが満杯の場合はブロックします。チャネルから受信すると解放になります。
sem := make(chan struct{}, 10)
func withSem(f func()) {
sem <- struct{}{} // acquire
defer func() { <-sem }() // release
f()
}セマフォを使ったジョブごとのgoroutine
ジョブごとに1つのgoroutineを起動し、セマフォで同時実行数を制限します。
sem := make(chan struct{}, 5)
for _, job := range jobs {
sem <- struct{}{}
go func(j Job) {
defer func() { <-sem }()
process(j)
}(job)
}最後にセマフォを空にする
すべてのgoroutineを起動した後、セマフォから値を取り出し続けて空にすることで、戻る前にすべての処理が完了することを保証します。
// After the loop, acquire all N slots (blocks until all goroutines release)
for i := 0; i < cap(sem); i++ {
sem <- struct{}{}
}golang.org/x/sync/semaphore
重み付きセマフォ(たとえば、必要なリソース量が異なるgoroutine)には、semaphore.Weighted型を使用します。
s := semaphore.NewWeighted(100)
// acquire 10 units
if err := s.Acquire(ctx, 10); err != nil { return err }
defer s.Release(10)
// do workcontextに対応した取得
重み付きセマフォのAcquireはcontextに対応しており、セマフォが利用可能になる前にキャンセルされた場合はエラーを返します。
TryAcquire
s.TryAcquire(n)は、n単位分がすぐに利用可能な場合にのみ取得し、それ以外の場合はfalseを返します。ブロックしない確認に便利です。
セマフォとワーカープールの違い
ワーカープールは、常駐する一定数のgoroutineで構成されます。セマフォでは、必要に応じてgoroutineを起動しながら、同時実行数に上限を設定できます。ジョブの到着率が大きく変動する場合は、セマフォを使用してください。
HTTPの同時実行数の制限
HTTPハンドラーまたはクライアントをセマフォでラップして、同時に実行される外部リクエストや受信ハンドラーgoroutineが多くなりすぎないようにします。
データベース接続数の制限
セマフォを使う代わりに、db.SetMaxOpenConns(n)とdb.SetMaxIdleConns(m)を設定します。sqlパッケージが接続プールの同時実行数を内部で管理します。
セマフォの公平性
バッファ付きチャネルのセマフォはおおむね公平です(送信でブロックされているgoroutineに対してFIFOで処理されます)が、厳密な保証はありません。重み付きセマフォのパッケージでは、より厳密な公平性が保証されます。
クイックチェック
バッファ付きチャネルはどのようにセマフォを実装しますか
振り返り: セマフォパターン
要点:
- 単純なセマフォには、バッファ付きチャネル sem := make(chan struct{}, N) を使用します
- 取得するときは送信し、解放するときは受信します。解放は必ず defer してください
- 重み付きでコンテキストに対応したバリアントには golang.org/x/sync/semaphore を使用します
- グループ単位で同時実行数を簡単に制限するには errgroup.SetLimit を使用します
よくある質問
「セマフォパターン」レッスンは無料ですか?
はい。「セマフォパターン」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Go Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Go Academyコースには全4レッスンが含まれています。
「セマフォパターン」で何を学びますか?
チャネルセマフォで並行性を制限します。 ブラウザで直接実行するハンズオンコードでGo Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Go Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのGo Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。
「セマフォパターン」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このGo Academyレッスンでコードを書いて実行できますか?
はい。すべてのGo Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。