std::condition_variable
std::condition_variable
是條件變量。
[Linux](https://www.2cto.com/os/linux/)
下使用 Pthread
庫中的 pthread_cond_*()
函數提供了與條件變量相關的功能。
當 std::condition_variable
對象的某個wait
函數被調用的時候,它使用 std::unique_lock
(通過 std::mutex
) 來鎖住當前線程。
當前線程會一直被阻塞,直到另外一個線程在相同的 std::condition_variable
對象上調用了 notification
函數來喚醒當前線程。
std::condition_variable
對象通常使用 std::unique_lock
來等待,
如果需要使用另外的 lockable
類型,可以使用std::condition_variable_any
類,本文後面會講到 std::condition_variable_any
的用法。
使用實例:
std::mutex mtx; // 全局互斥鎖.
std::condition_variable cv; // 全局條件變量.
bool ready = false; // 全局標誌位.
void do_print_id(int id)
{
std::unique_lock <std::mutex> lck(mtx);
while (!ready) // 如果標誌位不爲 true, 則等待...
cv.wait(lck); // 當前線程被阻塞, 當全局標誌位變爲 true 之後,
// 線程被喚醒, 繼續往下執行打印線程編號id.
std::cout << "thread " << id << '\n';
}
std::condition_variable::wait()
std::condition_variable
提供了兩種wait()
函數。當前線程調用wait()
後將被阻塞(此時當前線程應該獲得了鎖(mutex),不妨設獲得鎖 lck),直到另外某個線程調用 notify_* 喚醒了當前線程。
在線程被阻塞時,該函數會自動調用 lck.unlock() 釋放鎖,使得其他被阻塞在鎖競爭上的線程得以繼續執行。
另外,一旦當前線程獲得通知(notified,通常是另外某個線程調用 notify_* 喚醒了當前線程),wait()函數也是自動調用 lck.lock(),使得lck的狀態和 wait 函數被調用時相同。
使用例子:
// 主線程爲生產者線程, 生產 10 個物品.
for (int i = 0; i < 10; ++i) {
while (shipment_available())
std::this_thread::yield();
std::unique_lock <std::mutex> lck(mtx);
cargo = i + 1;
cv.notify_one();
}