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 つのスレッドを開始します。 メイン スレッドでは、 メソッド オーバーロードを使用してセマフォ数を最大に増やし、3 つのスレッドがセマフォ Release(Int32) に入るのを許可します。 各スレッドは、 メソッドを使用して 1 秒間待機し、作業をシミュレートした後、メソッド オーバーロードを呼び出してセマフォ Thread.Sleep Release() を解放します。 セマフォが解放されるたび、前のセマフォ数が表示されます。 コンソール メッセージはセマフォの使用を追跡します。 シミュレートされた作業間隔は、出力を読みやすくするために、スレッドごとにわずかに増加します。

#using <System.dll>
using namespace System;
using namespace System::Threading;

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

   // A padding interval to make the output more orderly.
   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 = gcnew Semaphore( 0,3 );
      
      // Create and start five numbered threads.
      //
      for ( int i = 1; i <= 5; i++ )
      {
         Thread^ t = gcnew Thread(
            gcnew 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( L"Main thread calls Release(3)." );
      _pool->Release( 3 );

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

private:
   static void Worker( Object^ num )
   {
      // Each worker thread begins by requesting the
      // semaphore.
      Console::WriteLine( L"Thread {0} begins and waits for the semaphore.", num );
      _pool->WaitOne();
      
      // A padding interval to make the output more orderly.
      int padding = Interlocked::Add( _padding, 100 );

      Console::WriteLine( L"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( L"Thread {0} releases the semaphore.", num );
      Console::WriteLine( L"Thread {0} previous semaphore count: {1}",
         num, _pool->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(0, 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(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 使用して、リソースのプールへのアクセスを制御します。 スレッドは、 クラスから継承された メソッドを呼び出してセマフォに入り、 メソッドを呼び出してセマフォ WaitOne WaitHandle を解放 Release します。

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

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

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

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

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

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

コンストラクター

Semaphore(Int32, Int32)

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

Semaphore(Int32, Int32, String)

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

Semaphore(Int32, Int32, String, Boolean)

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

Semaphore(Int32, Int32, String, Boolean, SemaphoreSecurity)

エントリ数の初期値と同時実行エントリの最大数を指定し、オプションでシステム セマフォ オブジェクトの名前を指定し、新しいシステム セマフォが作成されたかどうかを示す値を受け取る変数を指定し、システム セマフォのセキュリティ アクセス制御を指定して、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)

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

OpenExisting(String, SemaphoreRights)

既に存在する場合は、必要なセキュリティ アクセスで指定した名前付きセマフォを開きます。

Release()

セマフォから出て、前のカウントを返します。

Release(Int32)

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

SetAccessControl(SemaphoreSecurity)

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

ToString()

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

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

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

TryOpenExisting(String, SemaphoreRights, Semaphore)

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

WaitOne()

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

(継承元 WaitHandle)
WaitOne(Int32)

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

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

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

(継承元 WaitHandle)
WaitOne(TimeSpan)

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

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

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

(継承元 WaitHandle)

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

IDisposable.Dispose()

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

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

(継承元 WaitHandle)

拡張メソッド

GetAccessControl(Semaphore)

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

SetAccessControl(Semaphore, SemaphoreSecurity)

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

GetSafeWaitHandle(WaitHandle)

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

SetSafeWaitHandle(WaitHandle, SafeWaitHandle)

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

適用対象

スレッド セーフ

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

こちらもご覧ください