C++ std::condition_variable::notify_one()与notify_all()

std::condition_variable的成员函数notify_one()与notify_all()是用来唤醒阻塞在wait()的线程。假如有多个线程调用condition_variable::wait()陷入休眠之后。condition_variable的实现中有一个等待队列来保存堵塞在它之上的线程。当其他线程调用notify_one()时,只唤醒等待队列中的第一个线程;其余的线程不会被唤醒,需要等待再次调用notify_one()或者notify_all()才会唤醒。如果是调用notify_all():会唤醒所有等待队列中阻塞的线程,但是存在锁争用,只有一个线程能够获得锁。队列中的其他线程,会不断尝试获得锁,当第一个唤醒的线程释放锁之后,剩余的线程就能获得锁继续执行。
如下程序:

#include <iostream>
#include <condition_variable>
#include <thread>
#include <chrono>
 
std::condition_variable cv;
std::mutex cv_m; // This mutex is used for three purposes:
                 // 1) to synchronize accesses to i
                 // 2) to synchronize accesses to std::cerr
                 // 3) for the condition variable cv
int i = 0;
 
void waits()
{
    std::unique_lock<std::mutex> lk(cv_m);
    std::cerr << "Waiting... \n";
    cv.wait(lk);
    i++;
    std::cerr << "...finished waiting. i:"<<i<<std::endl;
}
 
void signals()
{
    std::this_thread::sleep_for(std::chrono::seconds(1));
    {
        std::lock_guard<std::mutex> lk(cv_m);
        std::cerr << "Notifying...\n";
    }
    cv.notify_all();
 
}
 
int main()
{
    std::thread t1(waits), t2(waits), t3(waits), t4(signals);
    t1.join(); 
    t2.join(); 
    t3.join();
    t4.join();
}

输出:

Waiting…
Waiting…
Waiting…
Notifying…
…finished waiting. i:1
…finished waiting. i:2
…finished waiting. i:3

main只调用一次notify_all()便激活了三个线程,这个三个线程依次执行。再来看一下notify_one()的情况

#include <iostream>
#include <condition_variable>
#include <thread>
#include <chrono>
 
std::condition_variable cv;
std::mutex cv_m; // This mutex is used for three purposes:
                 // 1) to synchronize accesses to i
                 // 2) to synchronize accesses to std::cerr
                 // 3) for the condition variable cv
int i = 0;
 
void waits()
{
    std::unique_lock<std::mutex> lk(cv_m);
    std::cerr << "Waiting... \n";
    cv.wait(lk);
    i++;
    std::cerr << "...finished waiting. i:"<<i<<std::endl;
}
 
void signals()
{
    std::this_thread::sleep_for(std::chrono::seconds(1));
    {
        std::lock_guard<std::mutex> lk(cv_m);
        std::cerr << "Notifying...\n";
    }
    cv.notify_one();
 
}
 
int main()
{
    std::thread t1(waits), t2(waits), t3(waits), t4(signals);
    t1.join(); 
    t2.join(); 
    t3.join();
    t4.join();
}

代码值改动了一个地方,输出为:

Waiting…
Waiting…
Waiting…
Notifying…
…finished waiting. i:1
execution expired

只有一个线程被激活

  • 4
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值