C++并发多线程--条件变量std::condition_variable的使用

1--std::condition_variable

        std::condition_variable 创建条件变量对象,其可以使用 wait(), notify_one() 等成员函数来实现多线程的条件交互,具体使用方法如下:

#include <iostream>
#include <thread>
#include <mutex>
#include <list>
#include <condition_variable>

class Sample{
public:
    // 模型发送消息
    void inMsgRecvQueue(){
        for(int i = 0; i < 1000; i++){
            std::cout << "Running inMsgRecvQueue(), insert one elem" << i << std::endl;
            std::unique_lock<std::mutex> guard1(mutex1);
            msgRecvQueue.push_back(i);
            // 将wait()所在线程唤醒
            // 假如wait()所在线程正在执行其余代码段,并不处于wait()的状态,此时notify_one()无效果
            cond.notify_one(); 
        }
        return;
    }
    // 模拟取消息
    void outMsgRecvQueue(){
        int command = 0;
        while(true){
            std::unique_lock<std::mutex> guard1(mutex1);
            // wait()用于等待,当lambda表达式返回true时,wait()直接返回
            // 当lambda表达式返回false时,wait()将解锁互斥量,并在本行堵塞
            // 堵塞直到某个线程调用notify_one()成员函数为止
            // 如果wait()没有第二个参数,则与lambda表达式返回false的效果一样
            // 即在本行堵塞,直到某个线程调用notify_one()成员函数
            // 当其他线程用notify_one()堵塞的wait()唤醒后,wait()线程将不断尝试获取锁
            // 当wait()成功获取锁后,将加锁并执行里面的内容(重新判断lambda表达式)
            cond.wait(guard1, [this]{
                if(!msgRecvQueue.empty()) return true;
                else return false;
            });

            // lambda表达式返回true,执行下面的内容
            command = msgRecvQueue.front();
            msgRecvQueue.pop_front();
            guard1.unlock(); // unique_lock可以随时解锁
            std::cout << "Running outMsgRecvQueue(), get one elem: "<< command << std::endl;
            if(command == 999) break; 
        }
    }

private:
    std::mutex mutex1;
    std::list<int> msgRecvQueue;
    std::condition_variable cond;
};

int main(int argc, char *argv[]){
    Sample sample1;
    std::thread OutMsg(&Sample::outMsgRecvQueue, &sample1);
    std::thread InMsg(&Sample::inMsgRecvQueue, &sample1);
    OutMsg.join();
    InMsg.join();
    return 0;
}

2--notify_one()和notify_all()

notify_one() 只能唤醒一个线程,当多个线程都等待被唤醒时,只会随机唤醒一个;

notify_all() 可以同时唤醒多个线程,,当多个线程都会等待被唤醒时,所有线程都会被唤醒;(被唤醒的多个线程可能会竞争同一个互斥锁(假设线程共用一个锁))

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C++11 标准提供了一些并发编程的指南,帮助程序员处理并发编程中的常见问题。这些指南可以帮助开发者实现高效、可靠的多线程应用。 首先,C++11 引入了 std::thread 类,它是一种线程的表示方式,可以方便地创建和管理线程。通过 std::thread,我们可以启动一个新线程并指定要执行的函数或函数对象。此外,std::thread 还提供了一系列的成员函数,如 join() 和 detach(),用于等待线程结束或分离线程。 其次,C++11 还引入了 std::mutex 和 std::lock_guard 类,用于解决多线程下的竞争条件问题。std::mutex 是一种互斥量,可以通过调用 lock() 和 unlock() 来控制对共享资源的访问。std::lock_guard 是一种锁保护类型,它的构造函数会自动在当前作用域上锁,析构函数会自动解锁,确保锁的正确使用。 此外,C++11 提供了 std::condition_variable 类,用于实现多线程间的条件变量通信。std::condition_variable 允许线程等待某个条件的发生,并在条件满足时由其他线程进行通知。 还有一个重要的概念是原子操作,C++11 提供了 std::atomic 类模板来实现无锁编程。通过 std::atomic,我们可以对共享变量进行原子操作,避免了需要锁保护的临界区域。 最后,C++11 还引入了 std::future 类模板和 std::promise 类模板,用于实现异步计算和线程间的数据传递。std::future 可以保存一个异步操作(如函数调用)的结果,而 std::promise 则可以在某个时间点设置这个结果。 综上所述,C++11 并发指南中的一些关键特性包括 std::thread、std::mutex、std::lock_guard、std::condition_variablestd::atomic、std::future 和 std::promise。它们为我们提供了一些基本工具和机制,帮助我们更加方便地编写多线程应用程序。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值