c++ condition_variable并行编程 (例:生产消费者模式)

1 condition_variable

参考:https://www.cnblogs.com/GuoXinxin/p/11675053.html

当 std::condition_variable对象的某个wait 函数被调用的时候,它使用 std::unique_lock(通过 std::mutex) 来锁住当前线程。
当前线程会一直被堵塞。直到另外一个线程在同样的 std::condition_variable 对象上调用了 notification 函数来唤醒当前线程。

1.1 condition_variable的wait()介绍

两种wait()函数:

void wait (unique_lock<mutex>& lck);
 
template <class Predicate>
void wait (unique_lock<mutex>& lck, Predicate pred);

当前线程调用 wait() 后将被堵塞(此时当前线程应该获得了锁(mutex),最好还是设获得锁 lck),直到另外某个线程调用 notify_* 唤醒了当前线程。

在线程被堵塞时,该函数会自己主动调用 lck.unlock() 释放锁,使得其它被堵塞在锁竞争上的线程得以继续运行。另外,一旦当前线程获得通知(notified,一般是另外某个线程调用 notify_* 唤醒了当前线程),wait()函数也是自己主动调用 lck.lock(),使得lck的状态和 wait 函数被调用时同样。

在另外一种情况下(即设置了 Predicate)。仅仅有当 pred 条件为false 时调用 wait() 才会堵塞当前线程。而且在收到其它线程的通知后仅仅有当 pred 为 true 时才会被解除堵塞。

1.2 std::condition_variable::notify_one()

唤醒某个等待(wait)线程。假设当前没有等待线程,则该函数什么也不做,假设同一时候存在多个等待线程,则唤醒某个线程是不确定的(unspecified)。

1.3 std::condition_variable::notify_all()

唤醒全部的等待(wait)线程。假设当前没有等待线程,则该函数什么也不做。

2 示例:多线程读取写入图片
#ifndef IMAGEBUFFER_H
#define IMAGEBUFFER_H

#include <opencv2/opencv.hpp>
#include <mutex>
#include <condition_variable>
#include <queue>


template<typename T>
class ConsumerProducerQueue
{

public:
    ConsumerProducerQueue(int mxsz,bool dropFrame) :
            maxSize(mxsz),dropFrame(dropFrame)
    { }

    void add(T request)
    {
        std::unique_lock<std::mutex> lock(mutex);
        if(dropFrame && isFull())
        {
            lock.unlock();
            return;
        }
        else {
            cond.wait(lock, [this]() { return !isFull(); });
            cpq.push(request);
            cond.notify_all();  //  唤醒用其它用条件变量wait()阻塞了的线程
        }
    }

    void consume(T &request)
    {
        std::unique_lock<std::mutex> lock(mutex);
        cond.wait(lock, [this]()
        { return !isEmpty(); });
        request = cpq.front();
        cpq.pop();
        //lock.unlock();
        cond.notify_all();

    }

    bool isFull() const
    {
        return cpq.size() >= maxSize;
    }

    bool isEmpty() const
    {
        return cpq.size() == 0;
    }

    int length() const
    {
        return cpq.size();
    }

    void clear()
    {
        std::unique_lock<std::mutex> lock(mutex);
        while (!isEmpty())
        {
            cpq.pop();
        }
        lock.unlock();
        cond.notify_all();
    }

private:
    std::condition_variable cond;
    std::mutex mutex;
    std::queue<T> cpq;
    int maxSize;
    bool dropFrame;
};


#endif

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值