std::counting_semaphore, std::binary_semaphore
定義於標頭檔案 <semaphore> |
||
template< std::ptrdiff_t LeastMaxValue = /* implementation-defined */ > class counting_semaphore; |
(1) | (C++20 起) |
using binary_semaphore = std::counting_semaphore<1>; |
(2) | (C++20 起) |
counting_semaphore
是一種輕量級的同步原語,可以控制對共享資源的訪問。與 std::mutex 不同,counting_semaphore
允許超過一個併發訪問同一資源,至少 LeastMaxValue
個併發訪問器。如果 LeastMaxValue
為負,則程式格式錯誤。binary_semaphore
是 std::counting_semaphore
的特化別名,其 LeastMaxValue
為 1。實現可以比 std::counting_semaphore
的預設實現更高效地實現 binary_semaphore
。一個 counting_semaphore
包含一個由建構函式初始化的內部計數器。此計數器在呼叫 acquire() 和相關方法時遞減,並在呼叫 release() 時遞增。當計數器為零時,acquire() 阻塞直到計數器遞增,但 try_acquire() 不阻塞;try_acquire_for() 和 try_acquire_until() 阻塞直到計數器遞增或達到超時。
類似於 std::condition_variable::wait(),counting_semaphore
的 try_acquire() 可能會虛假失敗。
std::counting_semaphore
的特化不是 可預設構造的 (DefaultConstructible)、可複製構造的 (CopyConstructible)、可移動構造的 (MoveConstructible)、可複製賦值的 (CopyAssignable) 或 可移動賦值的 (MoveAssignable)。
目錄 |
[編輯] 資料成員
成員名稱 (Member name) | 定義 |
counter (私有) |
型別為 std::ptrdiff_t 的內部計數器。 (僅用於闡釋的成員物件*) |
[編輯] 成員函式
構造一個 counting_semaphore (公共成員函式) | |
銷燬 counting_semaphore (公共成員函式) | |
operator= [已刪除] |
counting_semaphore 不可賦值(公共成員函式) |
操作 | |
增加內部計數器並解除阻塞獲取器 (公共成員函式) | |
遞減內部計數器或阻塞直到可以遞減 (公共成員函式) | |
嘗試遞減內部計數器而不阻塞 (公共成員函式) | |
嘗試遞減內部計數器,阻塞一段持續時間 (公共成員函式) | |
嘗試遞減內部計數器,阻塞直到某一時間點 (公共成員函式) | |
常量 | |
[靜態] |
返回內部計數器的最大可能值 (公共靜態成員函式) |
[編輯] 註解
正如其名稱所示,LeastMaxValue
是*最小*最大值,而不是*實際*最大值。因此 max() 可能返回大於 LeastMaxValue
的數字。
與 std::mutex 不同,counting_semaphore
不與執行執行緒繫結——例如,獲取訊號量可以在與釋放訊號量不同的執行緒上發生。所有對 counting_semaphore
的操作都可以併發執行,並且與特定的執行執行緒沒有任何關係,除了解構函式不能併發執行但可以在不同執行緒上執行。
訊號量也常用於信令/通知而不是互斥的語義,透過將訊號量初始化為 0,從而阻塞嘗試 acquire() 的接收者,直到通知者透過呼叫 release(n) 來“發出訊號”。在這方面,訊號量可以被視為 std::condition_variable 的替代方案,通常具有更好的效能。
特性測試宏 | 值 | 標準 | 特性 |
---|---|---|---|
__cpp_lib_semaphore |
201907L |
(C++20) | std::counting_semaphore , std::binary_semaphore |
[編輯] 示例
#include <chrono> #include <iostream> #include <semaphore> #include <thread> // global binary semaphore instances // object counts are set to zero // objects are in non-signaled state std::binary_semaphore smphSignalMainToThread{0}, smphSignalThreadToMain{0}; void ThreadProc() { // wait for a signal from the main proc // by attempting to decrement the semaphore smphSignalMainToThread.acquire(); // this call blocks until the semaphore's count // is increased from the main proc std::cout << "[thread] Got the signal\n"; // response message // wait for 3 seconds to imitate some work // being done by the thread using namespace std::literals; std::this_thread::sleep_for(3s); std::cout << "[thread] Send the signal\n"; // message // signal the main proc back smphSignalThreadToMain.release(); } int main() { // create some worker thread std::thread thrWorker(ThreadProc); std::cout << "[main] Send the signal\n"; // message // signal the worker thread to start working // by increasing the semaphore's count smphSignalMainToThread.release(); // wait until the worker thread is done doing the work // by attempting to decrement the semaphore's count smphSignalThreadToMain.acquire(); std::cout << "[main] Got the signal\n"; // response message thrWorker.join(); }
輸出
[main] Send the signal [thread] Got the signal [thread] Send the signal [main] Got the signal