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();
}