次の方法で共有


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.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(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 使用して、リソースのプールへのアクセスを制御します。 スレッドは、 クラスから継承された メソッドを WaitOne 呼び出してセマフォに WaitHandle 入り、 メソッドを呼び出してセマフォを Release 解放します。

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

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

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

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

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

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

注意事項

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

コンストラクター

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)

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

適用対象

スレッド セーフ

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

こちらもご覧ください