std::condition_variable

std::condition_variable

std::condition_variable,是C++11提供的条件变量,可用于同时阻塞一个线程或多个线程。一般的,生产者线程利用支持std::mutex的std::lock_guard/std::unique_lock修改共享变量后,并通知condition_variable。消费者线程获取同一个std::mutex(std::unique_lock所持有),并调用std::condition_variable的wait, wait_for, or wait_until。wait操作会释放互斥量,同时挂起该线程。当条件变量收到通知、超时到期或发生虚假唤醒时,线程被唤醒,互斥量也被原子地重新获取。需要注意的是,如果是虚假唤醒,线程应该检查条件并继续等待,以保证业务的正确性。

std::condition_variable::wait()

unconditional (1) void wait( std::unique_lockstd::mutex& lock );
predicate (2) template< class Predicate >
void wait( std::unique_lock< std::mutex >& lock, Predicate stop_waiting );

wait() 有两个重载,第二个算是一个语法糖,可用于在等待特定条件变为真时忽略虚假唤醒。相当于:

while (!stop_waiting()) {
    wait(lock);
}

注意:lock必须在wait()前调用,可以用来守护访问stop_waiting()。wait(lock)返回后会重新获取该lock。

示例:

#include 
#include 
#include 
#include 
#include 
 
std::mutex mtx;
std::condition_variable cv;
std::string data;
bool ready = false;
bool processed = false;
 
void worker_thread()
{
    // Wait until main() sends data
    std::unique_lock lock(mtx);
    cv.wait(lock, []{return ready;});
 
    // after the wait, we own the lock.
    std::cout << "Worker thread is processing data\n";
    data += " after processing";
 
    // Send data back to main()
    processed = true;
    std::cout << "Worker thread signals data processing completed\n";
 
    // Manual unlocking is done before notifying, to avoid waking up
    // the waiting thread only to block again (see notify_one for details)
    lock.unlock();
    cv.notify_one();
}
 
int main()
{
    std::thread worker(worker_thread);
 
    data = "Example data";
    // send data to the worker thread
    {
        std::lock_guard lock(mtx);
        ready = true;
        std::cout << "main() signals data ready for processing\n";
    }
    cv.notify_one();
 
    // wait for the worker
    {
        std::unique_lock lock(mtx);
        cv.wait(lock, []{return processed;});
    }
    std::cout << "Back in main(), data = " << data << '\n';
 
    worker.join();
}

输出:

main() signals data ready for processing
Worker thread is processing data
Worker thread signals data processing completed
Back in main(), data = Example data after processing

你可能感兴趣的:(c++)