0Pricing
Go Academy · レッスン

セマフォパターン

チャネルセマフォで並行性を制限します。

「セマフォパターン」は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 work

contextに対応した取得

重み付きセマフォの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フィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. パイプラインとステージのパターン
  2. 並行エラー処理のためのerrgroup
  3. セマフォパターン
  4. リーク検出とキャンセル
← Go Academyに戻る