C#
 Computer >> コンピューター >  >> プログラミング >> C#

【C#】セマフォ(Semaphore)でスレッドの同時アクセス数を制御する方法

セマフォ(Semaphore)とは

C#のSemaphore(セマフォ)クラスは、クリティカルセクションへ同時にアクセスできるスレッドの数に上限を設定するためのクラスです。データベース接続やファイルハンドルなど、限られたリソースプールへのアクセスを制御したい場面で活用されます。

セマフォは System.Threading.Semaphore 名前空間に属しており、セマフォ機能を実装するために必要なメソッドやプロパティがすべて提供されています。

セマフォの基本的な使い方

C#でセマフォを使用するのは非常にシンプルです。Semaphore オブジェクトのインスタンスを生成するだけで利用できます。コンストラクタには最低でも次の2つの引数を指定します。

  • 第1引数(初期カウント):最初に取得可能なエントリ数
  • 第2引数(最大カウント):同時にアクセスできるエントリの最大数

Semaphoreクラスの主なコンストラクタ

No.コンストラクタと説明
1Semaphore(Int32, Int32)
初期エントリ数と同時実行可能な最大エントリ数を指定して、Semaphoreクラスの新しいインスタンスを初期化します。
2Semaphore(Int32, Int32, String)
初期エントリ数と最大エントリ数を指定し、必要に応じてシステムセマフォオブジェクトの名前も指定して、新しいインスタンスを初期化します。
3Semaphore(Int32, Int32, String, Boolean)
初期エントリ数と最大エントリ数、必要に応じてシステムセマフォオブジェクトの名前を指定し、さらに新しいシステムセマフォが作成されたかどうかを示す値を受け取る変数を指定して、新しいインスタンスを初期化します。

サンプルコード

ここでは、同時実行可能な最大エントリ数を指定し、一部のエントリを予約できるSemaphoreコンストラクタを使用しています。

static Semaphore semaphore = new Semaphore(2, 2);

コード例

using System;
using System.Threading;

namespace Program
{
    class Demo
    {
        static Thread[] t = new Thread[5];
        static Semaphore semaphore = new Semaphore(2, 2);

        static void DoSomething()
        {
            Console.WriteLine("{0} = 待機中", Thread.CurrentThread.Name);
            semaphore.WaitOne();
            Console.WriteLine("{0} 開始!", Thread.CurrentThread.Name);
            Thread.Sleep(1000);
            Console.WriteLine("{0} 解放中...", Thread.CurrentThread.Name);
            semaphore.Release();
        }

        static void Main(string[] args)
        {
            for (int j = 0; j < 5; j++)
            {
                t[j] = new Thread(DoSomething);
                t[j].Name = "スレッド " + j;
                t[j].Start();
            }
            Console.Read();
        }
    }
}

実行結果

スレッド 2 = 待機中
スレッド 0 = 待機中
スレッド 3 = 待機中
スレッド 1 = 待機中
スレッド 4 = 待機中
スレッド 2 開始!
スレッド 1 開始!
スレッド 2 解放中...
スレッド 1 解放中...
スレッド 4 開始!
スレッド 3 開始!
スレッド 4 解放中...
スレッド 0 開始!
スレッド 3 解放中...
スレッド 0 解放中...

動作のポイント

  • WaitOne():セマフォのエントリを取得します。カウントが0の場合は、他のスレッドがRelease()を呼び出すまでブロックされます。
  • Release():取得していたエントリを解放し、待機中のスレッドがアクセスできるようにします。

この例では最大2スレッドまでしか同時に実行できないため、5つのスレッドのうち2つずつが順番に処理され、残りは待機状態になる様子が出力から確認できます。このようにセマフォを使うことで、同時アクセス数を柔軟に制御できます。

  1. JavaScriptで数字パターンを表示する方法【初心者向けサンプルコード】

    本記事では、テキスト入力欄とボタンを備えたJavaScript・HTMLプログラムの作成方法を解説します。ユーザーが入力欄に任意の数値(例:5)を入力してボタンをクリックすると、画面に以下のような数字パターンが表示される仕組みです。(n = 5 の場合の出力例)01 01 02 01 02 03 01 02 03 04 01 02 03 04 05仕組みのポイントこのパターンは二重ループ(ネストしたforループ)を使うことで実現できます。外側のループが「行」を制御し、内側のループがその行に表示する「数字の個数」を制御します。i 行目には 1 から i までの数字が順番に出力されるため、行が進む

  2. C++で五胞体数(ペンタトープ数)を求める方法

    五胞体数とは? 五胞体数(ペンタトープ数)は、パスカルの三角形の第5の対角線上に現れる数列として知られています。この数列を定義するには、パスカルの三角形に少なくとも5つの数が必要となるため、数列の最初の数はパスカルの三角形の第4行である 1 4 6 4 1 から始まります。 本チュートリアルでは、n番目の五胞体数を求める方法を解説します。まずは具体的な例を見てみましょう。 入力 : 1出力 : 1入力 : 4出力 : 35 以下の図から出力を確認できます。 この問題は数列に関するものなので、解法ではまず数列のパターンを見つけることから始めます。 解法のアプローチ このプログラムでは、数列の