前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【C++11】 让多线程开发变得简单--条件变量

【C++11】 让多线程开发变得简单--条件变量

作者头像
CPP开发前沿
发布2021-11-16 14:12:27
6720
发布2021-11-16 14:12:27
举报
文章被收录于专栏:CPP开发前沿CPP开发前沿

条件变量是C++11中提供的又一种线程同步机制,它可以阻塞一个或者多个线程,直到收到其它线程发出的超时或者通知才能够唤醒正在等待的线程,条件变量需要和互斥量配合使用,在C++ 11中共提供了两种条件变量。

  • condition_variable:配合std::unique_lock<std::mutex>使用
  • condition_variable_any:和lock、unlock配合使用,使用相对比较灵活但是性能也会比较差一点。

条件变量使用过程如下:

  • 获取互斥量
  • 循环检查条件,如果条件不满足则一直阻塞,反之继续执行
  • 线程执行完后调用notify_one或者notify_all唤醒等待的线程

在实际编码中,可以使用条件变量实现一个同步队列,同步队列可以作为线程安全的数据共享区,用户线程之间的数据读取,代码如下:

代码语言:javascript
复制
template<typename T>
class SynQueue
{
    bool IsFull() const
{
        return m_queue.size() ==  m_maxSize;
    }
    
    bool IsEmpty() const
{
        return m_queue.empty();
    }
public:
    SysQueue(int maxSize):m_maxSize(maxSize)
    {
        
    }
    
    void Put(const T &x)
{
        std::lock_guard<std::mutex> locker(m_mutex);
        while(IsFull())
        {
            cout<<"缓冲区满,需要等....."<<endl;
            m_notFull.wait(m_mutex);
        }
        
        m_queue.push_back(x);
        m_notEmpty.notify_one();
    }
    
    void Take(T &x)
{
         std::lock_guard<std::mutex> locker(m_mutex);
         while(IsEmpty())
         {
             cout<<"缓冲区空,需要等....."<<endl;
            m_notFull.wait(m_mutex);
         }
         
         x = m_queue.front();
         m_queue.pop_front();
         m_notFull.notify_one();
    }
    
    bool Empty()
{
        std::lock_guard<std::mutex> locker(m_mutex);
        return m_queue.empty();
    }
    
    bool Full()
{
        std::lock_guard<std::mutex> locker(m_mutex);
        return m_queue.size()==m_maxSize;
    }
    
    size_t Size()
    {
         std::lock_guard<std::mutex> locker(m_mutex);
        return m_queue.size();
    }
    
    int Count()
{
        return m_queue.size();
    }
private:
    std::list<T> m_queue;
    std::mutex m_mutex;
    std::condition_variable_any m_notEmpty;
    std::condition_variable_any m_notFull;
    int m_maxSize;
};

上面的代码实现了一个同步队列的功能,在队列没有满的情况下可以插入数据,如果队列满则会调用m_notFull进行阻塞等待其它线程发送通知,如果队列为空,则不能取出数据,会调用m_notEmpty条件变量进行阻塞,等待其它线程发送通知,然后继续执行。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-10-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 CPP开发前沿 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档