Boost库实现线程池学习及线程实现的异步调用

A.Boost线程池实现

参考自: Boost库实现线程池实例

原理:使用boost的thread_group存储多个线程,使用bind方法将要处理的函数转换成线程可调用的函数进行执行;使用队列存储待处理任务,利用Mutex实现队列线程安全。

#ifndef MYTHREADPOOL_H
#define MYTHREADPOOL_H

#include <iostream>
#include <queue>
#include <boost/bind.hpp>
#include <boost/thread.hpp>
#include <boost/function.hpp>
#include <boost/noncopyable.hpp>
using namespace boost;

typedef boost::function<void(void)> MyTask;
//任务队列--noncopyable
class MyTaskQueue : boost::noncopyable
{
private:
    std::queue<MyTask> m_taskQueue;
    boost::mutex m_mutex;//互斥锁
    boost::condition_variable_any m_cond;//条件变量
public:
    void push_Task(const MyTask& task){
        //加上互斥锁
        boost::unique_lock<boost::mutex> lock(m_mutex);
        m_taskQueue.push(task);
        //通知其他线程启动
        m_cond.notify_one();
    }

    MyTask pop_Task(){
        //加上互斥锁
        boost::unique_lock<boost::mutex> lock(m_mutex);
        if(m_taskQueue.empty())
        {
            //如果队列中没有任务,则等待互斥锁 
            m_cond.wait(lock);//
        }
        //指向队列首部
        MyTask task(m_taskQueue.front());
        //出队列  
        m_taskQueue.pop();
        return task;
    }
    int get_size()
    {
        return m_taskQueue.size();
    }
};

class MyThreadPool : boost::noncopyable
{
private:
    //任务队列
    MyTaskQueue m_taskQueue;
    //线程组 
    boost::thread_group m_threadGroup;
    int m_threadNum;
    /*
    volatile 被设计用来修饰被不同线程访问和修改的变量。
    volatile 告诉编译器i是随时可能发生变化的,每次使用它的时候必须从i的地址中读取,
    因而编译器生成的可执行码会重新从i的地址读取数据放在k中。 
    volatile可以保证对特殊地址的稳定访问,不会出错。
    */
    volatile bool is_run;
    void run(){//线程池中线程的处理函数
        while(is_run){
            //一直处理线程池的任务
            MyTask task = m_taskQueue.pop_Task();
            task();//运行bind的函数
        }
    }
public:
    MyThreadPool(int num):m_threadNum(num),is_run(false)//初始化列表
    {

    }
    ~MyThreadPool(){
        stop();
    }
    void init()
    {
        if(m_threadNum <= 0) return;
        is_run = true;
        for (int i=0;i<m_threadNum;i++)
        {
            //生成多个线程,绑定run函数,添加到线程组
            m_threadGroup.add_thread(
                new boost::thread(boost::bind(&MyThreadPool::run,this)));
        }
    }
    //停止线程池
    void stop()
    {
        is_run = false;
    }
    //添加任务
    void AddNewTask(const MyTask& task){
        m_taskQueue.push_Task(task);
    }
    void wait()
    {
        m_threadGroup.join_all();//等待线程池处理完成!
    }
};

typedef void (*pFunCallBack)(int i);
void CallBackFun(int i)
{
    std::cout << i <<" call back!"<<std::endl;
}

void ProcFun(int ti,pFunCallBack callback)
{
     std::cout<<"I am Task "<<ti<<std::endl; 
     //task
     for (int i=0;i<ti*100000000;i++)
     {
         i*i;
     }
     if(callback != NULL)callback(ti);
}


void CallBackFun2(int i)
{
    std::cout << i <<" call back! v2"<<std::endl;
}

int ProcFun2(int& ti)
{
    std::cout<<"I am Task "<<ti<<std::endl; 
    //task
    for (int i=0;i<ti*100000000;i++)
    {
        i*i;
    }
    return ti;
}


void testThreadPool()
{
    MyThreadPool tp(2);
    int taskNum = 4;
    for (int i=0;i<taskNum;i++)
    {
        MyTask task = boost::bind(ProcFun,i+1,CallBackFun);
        //放到线程池中处理,bind(f , i) will produce a "nullary" function object that takes no arguments and returns f(i),调用时,可传递任何类型的函数及参数!!!
        tp.AddNewTask(task);
    }

    tp.init();
    //等待线程池处理完成!  
    tp.wait();
}

#endif

 B.基于线程的异步调用实现

原理:使用线程实现异步调用,将耗时的操作放在线程中执行,待其执行完成后,调用回调函数执行后续操作。

//创建一个线程,执行耗时操作,等到操作完成,调用回调函数
void testAsyncCall(int i,pFunCallBack callfun)
{
    boost::thread th(boost::bind(ProcFun,i,callfun));
}
void testAsyncCall2(int i)
{
    //bind函数嵌套,回调函数 --bind(f, bind(g, _1))(x); // f(g(x))
    boost::thread th(boost::bind(CallBackFun2,boost::bind(ProcFun2,i)));
}

template <class ParaType,class RetType>
class MyTask2{
    typedef boost::function<RetType(ParaType&)> ProcFun;
    typedef boost::function<void(RetType)> CallBackFun;
protected:
    ProcFun m_procFun;
    CallBackFun m_callbackFun;
public:
    MyTask2():m_procFun(NULL),m_callbackFun(NULL){

    }
    MyTask2(ProcFun proc,CallBackFun callback):m_procFun(proc),m_callbackFun(callback){

    }
    ~MyTask2(){

    }
    void Run(ParaType& para){
        if(m_procFun!=NULL && m_callbackFun!=NULL)
        {
            m_callbackFun(m_procFun(para));
        }
    }
};


void testAsyncCall3(int para)//使用bind注册执行函数和回调函数
{
    MyTask2<int,int> tk(ProcFun2, CallBackFun2);
    //tk.Run(para);
    MyTask task = boost::bind(&MyTask2<int,int>::Run,tk,para);
    boost::thread th(task);
    //boost::thread th(boost::bind(&MyTask2<int,int>::Run,tk,para));
}

 

posted @ 2016-10-31 22:55  小小鸟的大梦想  阅读(10775)  评论(0编辑  收藏  举报