Semaphore 類別
定義
重要
部分資訊涉及發行前產品,在發行之前可能會有大幅修改。 Microsoft 對此處提供的資訊,不做任何明確或隱含的瑕疵擔保。
限制可以同時存取資源或資源集區的執行緒數目。
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
- 繼承
- 繼承
- 屬性
範例
下列程式碼範例會建立最大計數為 3 和初始計數為零的號志。 此範例會啟動五個執行緒,這會封鎖等候號志。 主執行緒會 Release(Int32) 使用 方法多載,將號志計數增加到其最大值,讓三個執行緒進入號志。 每個執行緒都會 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(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 方法釋放旗號。
每次執行緒進入號志時,都會遞減號志上的計數,並線上程釋放旗號時遞增。 當計數為零時,後續要求會封鎖,直到其他執行緒釋放旗號為止。 當所有線程都釋放旗號時,計數會位於建立號志時所指定的最大值。
沒有保證的順序,例如 FIFO 或 LIFO,封鎖的執行緒會進入號志。
執行緒可以重複呼叫 WaitOne 方法,多次進入號志。 若要釋放部分或全部這些專案,執行緒可以多次呼叫無 Release() 參數方法多載,也可以呼叫 Release(Int32) 方法多載,以指定要釋放的專案數。
類別 Semaphore 不會對 或 Release 的呼叫 WaitOne 強制執行執行緒識別。 程式設計人員必須負責確保執行緒不會釋放號志太多次。 例如,假設某個號誌的最大計數為 2,且執行緒 A 和執行緒 B 都進入號誌。 若執行緒 B 中的程式設計錯誤導致呼叫 Release 兩次,則兩次呼叫都會成功。 此時號誌計數已滿,當執行緒 A 終於呼叫 Release 時,就會擲回 SemaphoreFullException。
旗號有兩種類型:本機號志和具名系統號志。 如果您使用接受名稱的建構函式建立 Semaphore 物件,則會與該名稱的作業系統號志相關聯。 具名系統號志可在整個作業系統中看到,而且可用來同步處理常式的活動。 您可以建立多個 Semaphore 代表相同具名系統號志的物件,而且您可以使用 OpenExisting 方法來開啟現有的具名系統號志。
本機號志只存在於您的進程內。 在處理序內,只要是參考了本機 Semaphore 物件的執行緒,就可使用本機 Mutex。 每個 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 |
已淘汰.
已淘汰.
取得或設定原生 (Native) 的作業系統控制代碼。 (繼承來源 WaitHandle) |
SafeWaitHandle |
取得或設定原生 (Native) 的作業系統控制代碼。 (繼承來源 WaitHandle) |
方法
Close() |
釋放目前 WaitHandle 所持有的全部資源。 (繼承來源 WaitHandle) |
CreateObjRef(Type) |
建立包含所有相關資訊的物件,這些資訊是產生用來與遠端物件通訊的所需 Proxy。 (繼承來源 MarshalByRefObject) |
Dispose() |
釋放 WaitHandle 類別目前的執行個體所使用的全部資源。 (繼承來源 WaitHandle) |
Dispose(Boolean) |
當在衍生類別中覆寫時,釋放 WaitHandle 所使用的 Unmanaged 資源,並選擇性釋放 Managed 資源。 (繼承來源 WaitHandle) |
Equals(Object) |
判斷指定的物件是否等於目前的物件。 (繼承來源 Object) |
GetAccessControl() |
為具名系統號誌取得存取控制安全性。 |
GetHashCode() |
做為預設雜湊函式。 (繼承來源 Object) |
GetLifetimeService() |
已淘汰.
擷取控制這個執行個體存留期 (Lifetime) 原則的目前存留期服務物件。 (繼承來源 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) |
封鎖目前執行緒,直到目前的 WaitHandle 收到信號為止,使用 32 位元帶正負號的整數來指定時間間隔 (以毫秒為單位)。 (繼承來源 WaitHandle) |
WaitOne(Int32, Boolean) |
封鎖目前執行緒,直到目前的 WaitHandle 收到信號為止,使用 32 位元帶正負號的整數來指定時間間隔,並指定是否要先離開同步處理網域,再開始等候。 (繼承來源 WaitHandle) |
WaitOne(TimeSpan) |
封鎖目前執行緒,直到目前執行個體收到信號為止,使用 TimeSpan 來指定時間間隔。 (繼承來源 WaitHandle) |
WaitOne(TimeSpan, Boolean) |
封鎖目前執行緒,直到目前執行個體收到信號為止,使用 TimeSpan 來指定時間間隔,並指定是否要先離開同步處理網域,再開始等候。 (繼承來源 WaitHandle) |
明確介面實作
IDisposable.Dispose() |
此 API 支援此產品基礎結構,但無法直接用於程式碼之中。 釋放 WaitHandle 所使用的所有資源。 (繼承來源 WaitHandle) |
擴充方法
GetAccessControl(Semaphore) |
傳回所指定 |
SetAccessControl(Semaphore, SemaphoreSecurity) |
設定所指定旗號的安全性描述元。 |
GetSafeWaitHandle(WaitHandle) |
取得原生作業系統等候控制代碼的安全控制代碼。 |
SetSafeWaitHandle(WaitHandle, SafeWaitHandle) |
設定原生作業系統等候控制代碼的安全控制代碼。 |
適用於
執行緒安全性
此型別具備執行緒安全。