c++11 线程同步-条件变量

        标准 C++ 库提供了两个条件变量的实现:std::condition_variable 和 std::condition_variable_any。这两个实现都在头文件 <condition_variable>中声明,两者都需要和互斥锁一起使用。不同的是前者仅限于和 std::mutex 一起使用,而后者则可以与符合成为类似互斥锁的最低标准的任何东西一起使用,因此为_any 为后缀。因为 std::condition_variable 更加普遍,所以会有大小、性能或者操作系统 资源 方面的的形式的额外代价的可能 ,因此首先 std::condition_variable,除非需要额外的灵活性。

        以下是一个使用条件变量 std::condition_variable 的实例:

#include <stdlib.h>
#include <stdio.h>
#include <queue>
#include <mutex>
#include <memory>
#include <thread>
#include <chrono>
#include <condition_variable>

template <typename T>
class CThreadSafe_Queue
{
public:
    CThreadSafe_Queue()
    {

    }

    CThreadSafe_Queue(CThreadSafe_Queue &other)
    {
        std::lock_guard<std::mutex> lock(other.mMutex);
        mDataQueue = other.mDataQueue;
    }

    void push(T new_value)
    {
        std::lock_guard<std::mutex> lock(mMutex);
        mDataQueue.push(new_value);
        mCond.notify_one();
    }

    void wait_and_pop(T &value)
    {
        std::unique_lock<std::mutex> lock(mMutex);
        mCond.wait(lock, [this]{return !mDataQueue.empty();});
        value = mDataQueue.front();
        mDataQueue.pop();
    }

    std::shared_ptr<T> wait_and_pop()
    {
        std::unique_lock<std::mutex> lock(mMutex);
        mCond.wait(lock, [this]{return !mDataQueue.empty();});

        std::shared_ptr<T> ptr(std::make_shared<T>(mDataQueue.front()));
        mDataQueue.pop();

        return ptr;        
    }

    bool try_pop(T &value)
    {
        std::lock_guard<std::mutex> lock(mMutex);
        if(mDataQueue.empty())
        {
            return false;
        }
        value = mDataQueue.front();
        mDataQueue.pop();

        return true;
    }

    std::shared_ptr<T> try_pop()
    {
        std::lock_guard<std::mutex> lock(mMutex);
        if(mDataQueue.empty())
        {
            return std::shared_ptr<T> ();
        }

        std::shared_ptr<T> ptr(std::make_shared<T>(mDataQueue.front()));

        return ptr;
    }

    bool empty() const
    {
        std::lock_guard<std::mutex> lock(mMutex);
        return mDataQueue.empty();
    }

private:
    mutable std::mutex mMutex;
    std::queue<T> mDataQueue;
    std::condition_variable mCond;
};

static CThreadSafe_Queue<int> sThreadSafeQueue;



void producer()
{
    std::this_thread::sleep_for(std::chrono::seconds(3));
    printf("produce !\n");
    sThreadSafeQueue.push(200);
    std::this_thread::sleep_for(std::chrono::seconds(1));
}

void consume()
{
    printf("consume wait!\n");
    int value = 0;
    sThreadSafeQueue.wait_and_pop(value);
    printf("get vlaue = %d\n", value);
}

int main()
{
    //首先起一个消费线程,等待数据
    std::thread consumeThread(consume);
    std::this_thread::sleep_for(std::chrono::seconds(1));

    //其次起一个生产线程,产生数据
    std::thread producerThread(producer);

    consumeThread.join();
    producerThread.join();

    return 0;
}

main 函数里简单地实现了 2 个线程,一个生产,一个消费,消费线程首先启动,然后会进行 wait,当生产线程 push 一个数据时,条件变量调用 notify_one 进行通知,这样会唤醒执行 wait 的线程。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值