Semaphore クラス

定義

リソースまたはリソースのプールに同時にアクセスできるスレッドの数を制限します。

public ref class Semaphore sealed : System::Threading::WaitHandle
public sealed class Semaphore : System.Threading.WaitHandle
[System.Runtime.InteropServices.ComVisible(false)]
public sealed class Semaphore : System.Threading.WaitHandle
type Semaphore = class
    inherit WaitHandle
[<System.Runtime.InteropServices.ComVisible(false)>]
type Semaphore = class
    inherit WaitHandle
Public NotInheritable Class Semaphore
Inherits WaitHandle
継承
Semaphore
継承
属性

次のコード例では、最大カウントが 3 で、初期カウントが 0 のセマフォを作成します。 この例では、セマフォの待機をブロックする 5 つのスレッドを開始します。 メイン スレッドは、 Release(Int32) メソッドのオーバーロードを使用してセマフォの数を最大値に増やし、3 つのスレッドがセマフォに入れるようにします。 各スレッドは、 Thread.Sleep メソッドを使用して 1 秒間待機し、作業をシミュレートした後、 Release() メソッドオーバーロードを呼び出してセマフォを解放します。 セマフォが解放されるたびに、前のセマフォ数が表示されます。 コンソール メッセージはセマフォの使用を追跡します。 シミュレートされた作業間隔は、出力を読みやすくするために、スレッドごとにわずかに増加します。

using System;
using System.Threading;

public class Example
{
    // A semaphore that simulates a limited resource pool.
    //
    private static Semaphore _pool;

    // A padding interval to make the output more orderly.
    private static int _padding;

    public static void Main()
    {
        // Create a semaphore that can satisfy up to three
        // concurrent requests. Use an initial count of zero,
        // so that the entire semaphore count is initially
        // owned by the main program thread.
        //
        _pool = new Semaphore(initialCount: 0, maximumCount: 3);

        // Create and start five numbered threads. 
        //
        for(int i = 1; i <= 5; i++)
        {
            Thread t = new Thread(new ParameterizedThreadStart(Worker));

            // Start the thread, passing the number.
            //
            t.Start(i);
        }

        // Wait for half a second, to allow all the
        // threads to start and to block on the semaphore.
        //
        Thread.Sleep(500);

        // The main thread starts out holding the entire
        // semaphore count. Calling Release(3) brings the 
        // semaphore count back to its maximum value, and
        // allows the waiting threads to enter the semaphore,
        // up to three at a time.
        //
        Console.WriteLine("Main thread calls Release(3).");
        _pool.Release(releaseCount: 3);

        Console.WriteLine("Main thread exits.");
    }

    private static void Worker(object num)
    {
        // Each worker thread begins by requesting the
        // semaphore.
        Console.WriteLine("Thread {0} begins " +
            "and waits for the semaphore.", num);
        _pool.WaitOne();

        // A padding interval to make the output more orderly.
        int padding = Interlocked.Add(ref _padding, 100);

        Console.WriteLine("Thread {0} enters the semaphore.", num);
        
        // The thread's "work" consists of sleeping for 
        // about a second. Each thread "works" a little 
        // longer, just to make the output more orderly.
        //
        Thread.Sleep(1000 + padding);

        Console.WriteLine("Thread {0} releases the semaphore.", num);
        Console.WriteLine("Thread {0} previous semaphore count: {1}",
            num, _pool.Release());
    }
}
Imports System.Threading

Public Class Example

    ' A semaphore that simulates a limited resource pool.
    '
    Private Shared _pool As Semaphore

    ' A padding interval to make the output more orderly.
    Private Shared _padding As Integer

    <MTAThread> _
    Public Shared Sub Main()
        ' Create a semaphore that can satisfy up to three
        ' concurrent requests. Use an initial count of zero,
        ' so that the entire semaphore count is initially
        ' owned by the main program thread.
        '
        _pool = New Semaphore(0, 3)

        ' Create and start five numbered threads. 
        '
        For i As Integer = 1 To 5
            Dim t As New Thread(New ParameterizedThreadStart(AddressOf Worker))
            'Dim t As New Thread(AddressOf Worker)

            ' Start the thread, passing the number.
            '
            t.Start(i)
        Next i

        ' Wait for half a second, to allow all the
        ' threads to start and to block on the semaphore.
        '
        Thread.Sleep(500)

        ' The main thread starts out holding the entire
        ' semaphore count. Calling Release(3) brings the 
        ' semaphore count back to its maximum value, and
        ' allows the waiting threads to enter the semaphore,
        ' up to three at a time.
        '
        Console.WriteLine("Main thread calls Release(3).")
        _pool.Release(3)

        Console.WriteLine("Main thread exits.")
    End Sub

    Private Shared Sub Worker(ByVal num As Object)
        ' Each worker thread begins by requesting the
        ' semaphore.
        Console.WriteLine("Thread {0} begins " _
            & "and waits for the semaphore.", num)
        _pool.WaitOne()

        ' A padding interval to make the output more orderly.
        Dim padding As Integer = Interlocked.Add(_padding, 100)

        Console.WriteLine("Thread {0} enters the semaphore.", num)
        
        ' The thread's "work" consists of sleeping for 
        ' about a second. Each thread "works" a little 
        ' longer, just to make the output more orderly.
        '
        Thread.Sleep(1000 + padding)

        Console.WriteLine("Thread {0} releases the semaphore.", num)
        Console.WriteLine("Thread {0} previous semaphore count: {1}", _
            num, _
            _pool.Release())
    End Sub
End Class

注釈

Semaphore クラスを使用して、リソースのプールへのアクセスを制御します。 スレッドは、WaitHandle クラスから継承される WaitOne メソッドを呼び出してセマフォに入り、Release メソッドを呼び出してセマフォを解放します。

セマフォのカウントは、スレッドがセマフォに入るたびにデクリメントされ、スレッドがセマフォを解放するとインクリメントされます。 カウントが 0 の場合、後続の要求は、他のスレッドがセマフォを解放するまでブロックします。 すべてのスレッドがセマフォを解放すると、セマフォの作成時に指定された最大値がカウントされます。

FIFO や LIFO など、ブロックされたスレッドがセマフォに入る順序は保証されません。

スレッドは、 WaitOne メソッドを繰り返し呼び出すことによって、セマフォを複数回入力できます。 これらのエントリの一部またはすべてを解放するために、スレッドはパラメーターなしの Release() メソッド オーバーロードを複数回呼び出すか、解放するエントリの数を指定する Release(Int32) メソッド オーバーロードを呼び出すことができます。

Semaphore クラスは、WaitOneまたはReleaseの呼び出しにスレッド ID を適用しません。 スレッドがセマフォを解放しすぎないようにするのはプログラマの責任です。 たとえば、セマフォの最大数が 2 で、そのスレッド A とスレッド B の両方がセマフォに入ったとします。 スレッド B のプログラミング エラーにより、 Release が 2 回呼び出された場合、両方の呼び出しが成功します。 セマフォのカウントがいっぱいになっているときに、スレッド A も Release を呼び出すと、SemaphoreFullException がスローされます。

セマフォは、ローカル セマフォと名前付きシステム セマフォの 2 種類です。 名前を受け入れるコンストラクターを使用して Semaphore オブジェクトを作成すると、その名前のオペレーティング システム セマフォに関連付けられます。 名前付きシステム セマフォはオペレーティング システム全体で表示され、プロセスのアクティビティを同期するために使用できます。 同じ名前付きシステム セマフォを表す複数の Semaphore オブジェクトを作成でき、 OpenExisting メソッドを使用して既存の名前付きシステム セマフォを開くことができます。

ローカル セマフォは、プロセス内にのみ存在します。 ローカル Semaphore オブジェクトへの参照を持つプロセス内の任意のスレッドで使用できます。 各 Semaphore オブジェクトは個別のローカル セマフォです。

Caution

既定では、名前付きセマフォは、それを作成したユーザーに制限されません。 セマフォを複数回取得して解放しないことでセマフォを妨害するなど、他のユーザーがセマフォを開いて使用できる場合があります。 特定のユーザーへのアクセスを制限するには、コンストラクターのオーバーロードまたは SemaphoreAcl を使用し、名前付きセマフォの作成時に SemaphoreSecurity を渡します。 信頼されていないユーザーがコードを実行している可能性があるシステムでは、アクセス制限なしで名前付きセマフォを使用しないでください。

コンストラクター

名前 説明
Semaphore(Int32, Int32, String, Boolean, SemaphoreSecurity)

Semaphore クラスの新しいインスタンスを初期化し、エントリの初期数と同時エントリの最大数を指定し、必要に応じてシステム セマフォ オブジェクトの名前を指定し、新しいシステム セマフォが作成されたかどうかを示す値を受け取る変数を指定し、システム セマフォのセキュリティ アクセス制御を指定します。

Semaphore(Int32, Int32, String, Boolean)

エントリの初期数と同時実行エントリの最大数を指定し、必要に応じてシステム セマフォ オブジェクトの名前を指定し、新しいシステム セマフォが作成されたかどうかを示す値を受け取る変数を指定して、 Semaphore クラスの新しいインスタンスを初期化します。

Semaphore(Int32, Int32, String, NamedWaitHandleOptions, Boolean)

Semaphore クラスの新しいインスタンスを初期化します。エントリの初期数と同時エントリの最大数を指定し、必要に応じてシステム セマフォ オブジェクトの名前と、ユーザー スコープとセッション スコープのアクセスを設定するオプションを指定し、新しいシステム セマフォが作成されたかどうかを示す値を受け取る変数を指定します。

Semaphore(Int32, Int32, String, NamedWaitHandleOptions)

Semaphore クラスの新しいインスタンスを初期化し、エントリの初期数と同時エントリの最大数を指定し、必要に応じてシステム セマフォ オブジェクトの名前と、ユーザー スコープとセッション スコープのアクセスを設定するオプションを指定します。

Semaphore(Int32, Int32, String)

エントリの初期数と同時エントリの最大数を指定し、必要に応じてシステム セマフォ オブジェクトの名前を指定して、 Semaphore クラスの新しいインスタンスを初期化します。

Semaphore(Int32, Int32)

エントリの初期数と同時実行エントリの最大数を指定して、 Semaphore クラスの新しいインスタンスを初期化します。

フィールド

名前 説明
WaitTimeout

待機ハンドルが通知される前に、 WaitAny(WaitHandle[], Int32, Boolean) 操作がタイムアウトしたことを示します。 このフィールドは定数です。

(継承元 WaitHandle)

プロパティ

名前 説明
Handle
古い.
古い.

ネイティブ オペレーティング システム ハンドルを取得または設定します。

(継承元 WaitHandle)
SafeWaitHandle

ネイティブ オペレーティング システム ハンドルを取得または設定します。

(継承元 WaitHandle)

メソッド

名前 説明
Close()

現在の WaitHandleによって保持されているすべてのリソースを解放します。

(継承元 WaitHandle)
CreateObjRef(Type)

リモート オブジェクトとの通信に使用されるプロキシの生成に必要なすべての関連情報を含むオブジェクトを作成します。

(継承元 MarshalByRefObject)
Dispose()

WaitHandle クラスの現在のインスタンスで使用されているすべてのリソースを解放します。

(継承元 WaitHandle)
Dispose(Boolean)

派生クラスでオーバーライドされると、 WaitHandleによって使用されるアンマネージ リソースが解放され、必要に応じてマネージド リソースが解放されます。

(継承元 WaitHandle)
Equals(Object)

指定されたオブジェクトが現在のオブジェクトと等しいかどうかを判断します。

(継承元 Object)
GetAccessControl()

名前付きシステム セマフォのアクセス制御セキュリティを取得します。

GetHashCode()

既定のハッシュ関数として機能します。

(継承元 Object)
GetLifetimeService()
古い.

このインスタンスの有効期間ポリシーを制御する現在の有効期間サービス オブジェクトを取得します。

(継承元 MarshalByRefObject)
GetType()

現在のインスタンスの Type を取得します。

(継承元 Object)
InitializeLifetimeService()
古い.

このインスタンスの有効期間ポリシーを制御する有効期間サービス オブジェクトを取得します。

(継承元 MarshalByRefObject)
MemberwiseClone()

現在の Objectの簡易コピーを作成します。

(継承元 Object)
MemberwiseClone(Boolean)

現在の MarshalByRefObject オブジェクトの簡易コピーを作成します。

(継承元 MarshalByRefObject)
OpenExisting(String, NamedWaitHandleOptions)

指定した名前付きセマフォが既に存在する場合は開きます。 オプションが現在のユーザーのみに設定されている場合、オブジェクトのアクセス制御は呼び出し元のユーザーに対して検証されます。

OpenExisting(String, SemaphoreRights)

指定した名前付きセマフォが既に存在する場合は、目的のセキュリティ アクセスを使用して開きます。

OpenExisting(String)

指定した名前付きセマフォが既に存在する場合は開きます。

Release()

セマフォを終了し、前のカウントを返します。

Release(Int32)

指定した回数だけセマフォを終了し、前のカウントを返します。

SetAccessControl(SemaphoreSecurity)

名前付きシステム セマフォのアクセス制御セキュリティを設定します。

ToString()

現在のオブジェクトを表す文字列を返します。

(継承元 Object)
TryOpenExisting(String, NamedWaitHandleOptions, Semaphore)

指定した名前付きセマフォが既に存在する場合は開き、操作が成功したかどうかを示す値を返します。 オプションが現在のユーザーのみに設定されている場合、オブジェクトのアクセス制御は呼び出し元のユーザーに対して検証されます。

TryOpenExisting(String, Semaphore)

指定した名前付きセマフォが既に存在する場合は開き、操作が成功したかどうかを示す値を返します。

TryOpenExisting(String, SemaphoreRights, Semaphore)

指定した名前付きセマフォが既に存在する場合は、目的のセキュリティ アクセスを使用して開き、操作が成功したかどうかを示す値を返します。

WaitOne()

現在の WaitHandle がシグナルを受信するまで、現在のスレッドをブロックします。

(継承元 WaitHandle)
WaitOne(Int32, Boolean)

32 ビット符号付き整数を使用して時間間隔を指定し、待機前に同期ドメインを終了するかどうかを指定して、現在の WaitHandle がシグナルを受信するまで、現在のスレッドをブロックします。

(継承元 WaitHandle)
WaitOne(Int32)

現在の WaitHandle がシグナルを受信するまで、32 ビット符号付き整数を使用してミリ秒単位で時間間隔を指定するまで、現在のスレッドをブロックします。

(継承元 WaitHandle)
WaitOne(TimeSpan, Boolean)

TimeSpanを使用して時間間隔を指定し、待機前に同期ドメインを終了するかどうかを指定して、現在のインスタンスがシグナルを受信するまで、現在のスレッドをブロックします。

(継承元 WaitHandle)
WaitOne(TimeSpan)

TimeSpanを使用して時間間隔を指定して、現在のインスタンスがシグナルを受信するまで、現在のスレッドをブロックします。

(継承元 WaitHandle)

明示的なインターフェイスの実装

名前 説明
IDisposable.Dispose()

この API は製品インフラストラクチャをサポートします。コードから直接使用するものではありません。

WaitHandleによって使用されるすべてのリソースを解放します。

(継承元 WaitHandle)

拡張メソッド

名前 説明
GetAccessControl(Semaphore)

指定した semaphoreのセキュリティ記述子を返します。

GetSafeWaitHandle(WaitHandle)

ネイティブ オペレーティング システムの待機ハンドルのセーフ ハンドルを取得します。

SetAccessControl(Semaphore, SemaphoreSecurity)

指定したセマフォのセキュリティ記述子を設定します。

SetSafeWaitHandle(WaitHandle, SafeWaitHandle)

ネイティブ オペレーティング システムの待機ハンドルのセーフ ハンドルを設定します。

適用対象

スレッド セーフ

この型はスレッド セーフです。

こちらもご覧ください