Semaphore 類別

定義

限制可以同時存取資源或資源集區的執行緒數目。Limits the number of threads that can access a resource or pool of resources concurrently.

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
繼承
屬性

範例

下列程式碼範例會建立最多三個計數和初始計數為零的信號。The following code example creates a semaphore with a maximum count of three and an initial count of zero. 此範例會啟動五個執行緒,以封鎖等候信號。The example starts five threads, which block waiting for the semaphore. 主執行緒使用 Release(Int32) 方法多載,將信號計數增加到最大值,允許三個執行緒進入信號。The main thread uses the Release(Int32) method overload to increase the semaphore count to its maximum, allowing three threads to enter the semaphore. 每個執行緒會使用 Thread.Sleep 方法來等候一秒、模擬工作,然後呼叫方法多載 Release() 來釋放信號。Each thread uses the Thread.Sleep method to wait for one second, to simulate work, and then calls the Release() method overload to release the semaphore. 每次釋放信號時,就會顯示先前的信號計數。Each time the semaphore is released, the previous semaphore count is displayed. 主控台訊息追蹤信號使用。Console messages track semaphore use. 每個執行緒的模擬工作間隔會稍微增加,讓輸出變得更容易閱讀。The simulated work interval is increased slightly for each thread, to make the output easier to read.

#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 類別來控制資源集區的存取權。Use the Semaphore class to control access to a pool of resources. 執行緒會藉由呼叫方法 WaitOne (繼承自類別)來進入信號, WaitHandle 然後藉由呼叫方法來釋放信號 ReleaseThreads enter the semaphore by calling the WaitOne method, which is inherited from the WaitHandle class, and release the semaphore by calling the Release method.

每次執行緒進入信號時,會減少信號的計數,並線上程釋放信號時遞增。The count on a semaphore is decremented each time a thread enters the semaphore, and incremented when a thread releases the semaphore. 當計數為零時,後續要求會封鎖,直到其他執行緒釋放信號為止。When the count is zero, subsequent requests block until other threads release the semaphore. 當所有線程都釋出信號時,計數就會是建立信號時所指定的最大值。When all threads have released the semaphore, the count is at the maximum value specified when the semaphore was created.

沒有任何保證的順序,例如 FIFO 或 LIFO,封鎖的執行緒會在此輸入信號。There is no guaranteed order, such as FIFO or LIFO, in which blocked threads enter the semaphore.

執行緒可以重複呼叫方法,多次進入信號 WaitOneA thread can enter the semaphore multiple times, by calling the WaitOne method repeatedly. 若要釋放部分或全部的專案,執行緒可以多次呼叫無參數 Release() 方法多載,或呼叫方法多載 Release(Int32) ,以指定要釋放的專案數。To release some or all of these entries, the thread can call the parameterless Release() method overload multiple times, or it can call the Release(Int32) method overload that specifies the number of entries to be released.

Semaphore類別不會在對或的呼叫上強制執行執行緒身分識別 WaitOne ReleaseThe Semaphore class does not enforce thread identity on calls to WaitOne or Release. 程式設計人員必須負責確保執行緒不會太多次釋放信號。It is the programmer's responsibility to ensure that threads do not release the semaphore too many times. 例如,假設某個號誌的最大計數為 2,且執行緒 A 和執行緒 B 都進入號誌。For example, suppose a semaphore has a maximum count of two, and that thread A and thread B both enter the semaphore. 如果執行緒 B 中的程式設計錯誤導致呼叫 Release 兩次,則這兩個呼叫都會成功。If a programming error in thread B causes it to call Release twice, both calls succeed. 此時號誌計數已滿,當執行緒 A 終於呼叫 Release 時,就會擲回 SemaphoreFullExceptionThe count on the semaphore is full, and when thread A eventually calls Release, a SemaphoreFullException is thrown.

信號有兩種類型:本機信號和命名系統信號。Semaphores are of two types: local semaphores and named system semaphores. 如果您 Semaphore 使用接受名稱的函式來建立物件,它會與該名稱的作業系統信號產生關聯。If you create a Semaphore object using a constructor that accepts a name, it is associated with an operating-system semaphore of that name. 在整個作業系統中都可以看見命名系統信號,而且可以用來同步處理處理常式的活動。Named system semaphores are visible throughout the operating system, and can be used to synchronize the activities of processes. 您可以建立多個 Semaphore 代表相同命名系統信號的物件,而且可以使用 OpenExisting 方法來開啟現有的已命名系統信號。You can create multiple Semaphore objects that represent the same named system semaphore, and you can use the OpenExisting method to open an existing named system semaphore.

本機信號只存在於您的進程內。A local semaphore exists only within your process. 在處理序內,只要是參考了本機 Semaphore 物件的執行緒,就可使用本機 Mutex。It can be used by any thread in your process that has a reference to the local Semaphore object. 每個 Semaphore 物件都是個別的本機信號。Each Semaphore object is a separate local semaphore.

建構函式

Semaphore(Int32, Int32)

初始化 Semaphore 類別的新執行個體,以及指定並行項目的最大數目及選擇性地保留某些項目。Initializes a new instance of the Semaphore class, specifying the initial number of entries and the maximum number of concurrent entries.

Semaphore(Int32, Int32, String)

初始化 Semaphore 類別的新執行個體,然後指定初始項目數目與並行項目的最大數目,以及選擇性地指定系統旗號物件的名稱。Initializes a new instance of the Semaphore class, specifying the initial number of entries and the maximum number of concurrent entries, and optionally specifying the name of a system semaphore object.

Semaphore(Int32, Int32, String, Boolean)

初始化 Semaphore 類別的新執行個體,然後指定初始項目物件數目與並行項目的最大數目,選擇性地指定系統號誌物件的名稱,以及指定接收值的變數,指出是否已建立新的系統號誌。Initializes a new instance of the Semaphore class, specifying the initial number of entries and the maximum number of concurrent entries, optionally specifying the name of a system semaphore object, and specifying a variable that receives a value indicating whether a new system semaphore was created.

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

初始化 Semaphore 類別的新執行個體,然後指定初始項目數目與並行項目的最大數目,選擇性地指定系統號誌物件的名稱,指定接收值的變數 (以指示是否已建立新的系統號誌),以及指定系統號誌的安全性存取控制。Initializes a new instance of the Semaphore class, specifying the initial number of entries and the maximum number of concurrent entries, optionally specifying the name of a system semaphore object, specifying a variable that receives a value indicating whether a new system semaphore was created, and specifying security access control for the system semaphore.

欄位

WaitTimeout

表示 WaitAny(WaitHandle[], Int32, Boolean) 作業在發出任何等候控制代碼信號之前便已逾時。Indicates that a WaitAny(WaitHandle[], Int32, Boolean) operation timed out before any of the wait handles were signaled. 這個欄位為常數。This field is constant.

(繼承來源 WaitHandle)

屬性

Handle
已過時。

取得或設定原生 (Native) 的作業系統控制代碼。Gets or sets the native operating system handle.

(繼承來源 WaitHandle)
SafeWaitHandle

取得或設定原生 (Native) 的作業系統控制代碼。Gets or sets the native operating system handle.

(繼承來源 WaitHandle)

方法

Close()

釋放目前 WaitHandle 所持有的全部資源。Releases all resources held by the current WaitHandle.

(繼承來源 WaitHandle)
CreateObjRef(Type)

建立包含所有相關資訊的物件,這些資訊是產生用來與遠端物件通訊的所需 Proxy。Creates an object that contains all the relevant information required to generate a proxy used to communicate with a remote object.

(繼承來源 MarshalByRefObject)
Dispose()

釋放 WaitHandle 類別目前的執行個體所使用的全部資源。Releases all resources used by the current instance of the WaitHandle class.

(繼承來源 WaitHandle)
Dispose(Boolean)

當在衍生類別中覆寫時,釋放 WaitHandle 所使用的 Unmanaged 資源,並選擇性釋放 Managed 資源。When overridden in a derived class, releases the unmanaged resources used by the WaitHandle, and optionally releases the managed resources.

(繼承來源 WaitHandle)
Equals(Object)

判斷指定的物件是否等於目前的物件。Determines whether the specified object is equal to the current object.

(繼承來源 Object)
GetAccessControl()

為具名系統號誌取得存取控制安全性。Gets the access control security for a named system semaphore.

GetHashCode()

做為預設雜湊函式。Serves as the default hash function.

(繼承來源 Object)
GetLifetimeService()
已過時。

擷取控制這個執行個體存留期 (Lifetime) 原則的目前存留期服務物件。Retrieves the current lifetime service object that controls the lifetime policy for this instance.

(繼承來源 MarshalByRefObject)
GetType()

取得目前執行個體的 TypeGets the Type of the current instance.

(繼承來源 Object)
InitializeLifetimeService()
已過時。

取得存留期服務物件,以控制這個執行個體的存留期原則。Obtains a lifetime service object to control the lifetime policy for this instance.

(繼承來源 MarshalByRefObject)
MemberwiseClone()

建立目前 Object 的淺層複製。Creates a shallow copy of the current Object.

(繼承來源 Object)
MemberwiseClone(Boolean)

建立目前 MarshalByRefObject 物件的淺層複本。Creates a shallow copy of the current MarshalByRefObject object.

(繼承來源 MarshalByRefObject)
OpenExisting(String)

開啟指定的具名號誌 (如果已經存在)。Opens the specified named semaphore, if it already exists.

OpenExisting(String, SemaphoreRights)

使用所需的安全性存取權,開啟指定的具名號誌 (如果已經存在)。Opens the specified named semaphore, if it already exists, with the desired security access.

Release()

結束號誌,並傳回上一個計數。Exits the semaphore and returns the previous count.

Release(Int32)

以指定的次數結束號誌,並回到上一個計數。Exits the semaphore a specified number of times and returns the previous count.

SetAccessControl(SemaphoreSecurity)

為具名系統號誌設定存取控制安全性。Sets the access control security for a named system semaphore.

ToString()

傳回代表目前物件的字串。Returns a string that represents the current object.

(繼承來源 Object)
TryOpenExisting(String, Semaphore)

開啟指定的具名號誌 (如果已經存在),並傳回值,指出作業是否成功。Opens the specified named semaphore, if it already exists, and returns a value that indicates whether the operation succeeded.

TryOpenExisting(String, SemaphoreRights, Semaphore)

使用所需的安全性存取權,開啟指定的具名號誌 (如果已經存在),並傳回值,指出作業是否成功。Opens the specified named semaphore, if it already exists, with the desired security access, and returns a value that indicates whether the operation succeeded.

WaitOne()

封鎖目前的執行緒,直到目前的 WaitHandle 收到訊號為止。Blocks the current thread until the current WaitHandle receives a signal.

(繼承來源 WaitHandle)
WaitOne(Int32)

封鎖目前執行緒,直到目前的 WaitHandle 收到信號為止,使用 32 位元帶正負號的整數來指定時間間隔 (以毫秒為單位)。Blocks the current thread until the current WaitHandle receives a signal, using a 32-bit signed integer to specify the time interval in milliseconds.

(繼承來源 WaitHandle)
WaitOne(Int32, Boolean)

封鎖目前執行緒,直到目前的 WaitHandle 收到信號為止,使用 32 位元帶正負號的整數來指定時間間隔,並指定是否要先離開同步處理網域,再開始等候。Blocks the current thread until the current WaitHandle receives a signal, using a 32-bit signed integer to specify the time interval and specifying whether to exit the synchronization domain before the wait.

(繼承來源 WaitHandle)
WaitOne(TimeSpan)

封鎖目前執行緒,直到目前執行個體收到信號為止,使用 TimeSpan 來指定時間間隔。Blocks the current thread until the current instance receives a signal, using a TimeSpan to specify the time interval.

(繼承來源 WaitHandle)
WaitOne(TimeSpan, Boolean)

封鎖目前執行緒,直到目前執行個體收到信號為止,使用 TimeSpan 來指定時間間隔,並指定是否要先離開同步處理網域,再開始等候。Blocks the current thread until the current instance receives a signal, using a TimeSpan to specify the time interval and specifying whether to exit the synchronization domain before the wait.

(繼承來源 WaitHandle)

明確介面實作

IDisposable.Dispose()

此 API 支援此產品基礎結構,但無法直接用於程式碼之中。

釋放 WaitHandle 所使用的所有資源。Releases all resources used by the WaitHandle.

(繼承來源 WaitHandle)

擴充方法

GetAccessControl(Semaphore)

傳回所指定 semaphore 的安全性描述元。Returns the security descriptors for the specified semaphore.

SetAccessControl(Semaphore, SemaphoreSecurity)

設定所指定旗號的安全性描述元。Sets the security descriptors for the specified semaphore.

GetSafeWaitHandle(WaitHandle)

取得原生作業系統等候控制代碼的安全控制代碼。Gets the safe handle for a native operating system wait handle.

SetSafeWaitHandle(WaitHandle, SafeWaitHandle)

設定原生作業系統等候控制代碼的安全控制代碼。Sets a safe handle for a native operating system wait handle.

適用於

執行緒安全性

此型別具備執行緒安全。This type is thread safe.