用c++11的bind,function,boost::condition_variable实现的一个线程安全的任务队列

用bind将需要执行的任务包装成function<void()> 放入队列std::queue<function<void()>> 中。
然后在队列中取出调用执行。

当线程间的共享数据发生变化的时候,可以通过condition_variable来通知其他的线程。消费者wait 直到生产者通知其状态发生改变,Condition_variable是使用方法如下:

·当持有锁之后,线程调用wait

·wait解开持有的互斥锁(mutex),阻塞本线程,并将自己加入到唤醒队列中

·当收到通知(notification),该线程从阻塞中恢复,并加入互斥锁队列(mutex queue)

FunQueue.h文件

#include <queue>
#include <functional>
#include <boost/thread.hpp>

typedef std::function<void()> Data;
class CFunQueue
{
public:
    void push(Data const& data);
    bool empty() const;
    bool try_pop(Data& popped_value);
    void wait_and_pop(Data& popped_value);
private:
    std::queue<Data> the_queue;
    mutable boost::mutex the_mutex;
    boost::condition_variable the_condition_variable;
};

FunQueue.cpp文件

#include "FunQueue.h"


void CFunQueue::push(Data const& data)
{
    boost::mutex::scoped_lock lock(the_mutex);
    the_queue.push(data);
    lock.unlock();
    the_condition_variable.notify_one();
}

bool CFunQueue::empty() const
{
    boost::mutex::scoped_lock lock(the_mutex);
    return the_queue.empty();
}

bool CFunQueue::try_pop(Data& popped_value)
{
    boost::mutex::scoped_lock lock(the_mutex);
    if (the_queue.empty())
    {
        return false;
    }

    popped_value = the_queue.front();
    the_queue.pop();
    return true;
}

void CFunQueue::wait_and_pop(Data& popped_value)
{
    boost::mutex::scoped_lock lock(the_mutex);
    while (the_queue.empty())
    {
        the_condition_variable.wait(lock);
    }

    popped_value = the_queue.front();
    the_queue.pop();
}

main函数

#include <iostream>
#include <string>
#include <boost/thread.hpp>
#include "FunQueue.h"
using namespace std;
void print1()
{
    cout << "任务1." << endl;
}
void print2(string name)
{
    cout << "任务2." << name << endl;
}
class A
{
public:
    void print3(int i)
    {
        cout << "任务3." << i << endl;
    }
    static void print4()
    {
        cout << "任务4." << endl;
    }
};
A a;
CFunQueue funQueue;
void run1()
{
    cout << "线程1:睡200微秒" << endl;
    boost::this_thread::sleep(boost::posix_time::milliseconds(200));
    funQueue.push(bind(print1));
    funQueue.push(bind(print2,"222"));
    funQueue.push(bind(&A::print3, a,333));
    funQueue.push(bind(&A::print4));
    cout << "线程1:任务输入完成" << endl;
}
void run2()
{
    Data f;
    // 尝试取出任务
    bool ret = funQueue.try_pop(f);
    if (ret)
    {
        cout << "尝试取出任务成功" << endl;
        f();
    }
    else
        cout << "尝试取出任务失败" << endl;
    cout << "阻塞等待取出任务" << endl;
    funQueue.wait_and_pop(f);
    f();
    funQueue.wait_and_pop(f);
    f();
    cout << "线程2:睡200微秒" << endl;
    boost::this_thread::sleep(boost::posix_time::milliseconds(200));
    ret = funQueue.try_pop(f);
    if (ret)
    {
        cout << "尝试取出任务成功" << endl;
        f();
    }
    else
        cout << "尝试取出任务失败" << endl;
    ret = funQueue.try_pop(f);
    if (ret)
    {
        cout << "尝试取出任务成功" << endl;
        f();
    }
    else
        cout << "尝试取出任务失败" << endl;
}
int main()
{
    boost::thread_group thr_grp;
    thr_grp.create_thread(bind(run1));
    thr_grp.create_thread(bind(run2));
    thr_grp.join_all();
    getchar();
    return 0;
}

输出
这里写图片描述

bool CFunQueue::try_pop(Data& popped_value)

这个方法是立即返回的,如果有任务,会取出任务,返回true,如果没有任务,则返回false。

void CFunQueue::wait_and_pop(Data& popped_value)

这个方法是阻塞的,会一直等待知道有人向队列里面push任务。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值