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 <= ) return;
is_run = true;
for (int i=;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=;i<ti*;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=;i<ti*;i++)
{
i*i;
}
return ti;
} void testThreadPool()
{
MyThreadPool tp();
int taskNum = ;
for (int i=;i<taskNum;i++)
{
MyTask task = boost::bind(ProcFun,i+,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));
}

Boost库实现线程池学习及线程实现的异步调用的更多相关文章

  1. 【Java多线程】线程池学习

    Java线程池学习 众所周知,Java不仅提供了线程,也提供了线程池库给我们使用,那么今天来学学线程池的具体使用以及线程池基本实现原理分析. ThreadPoolExecutor ThreadPool ...

  2. Java线程池学习

    Java线程池学习 Executor框架简介 在Java 5之后,并发编程引入了一堆新的启动.调度和管理线程的API.Executor框架便是Java 5中引入的,其内部使用了线程池机制,它在java ...

  3. Java线程池学习总结

    一 使用线程池的好处 池化技术相比大家已经屡见不鲜了,线程池.数据库连接池.Http 连接池等等都是对这个思想的应用.池化技术的思想主要是为了减少每次获取资源的消耗,提高对资源的利用率. 线程池提供了 ...

  4. android中的线程池学习笔记

    阅读书籍: Android开发艺术探索 Android开发进阶从小工到专家 对线程池原理的简单理解: 创建多个线程并且进行管理,提交的任务会被线程池指派给其中的线程进行执行,通过线程池的统一调度和管理 ...

  5. Java 线程池学习

    Java里面线程池的顶级接口是Executor,但是严格意义上讲Executor并不是一个线程池,而只是一个执行线程的工具.真正的线程池接口是ExecutorService. 下面这张图完整描述了线程 ...

  6. Java线程池学习心得

    一.普通线程和线程池的对比 new Thread的弊端如下: a. 每次new Thread新建对象性能差.b. 线程缺乏统一管理,可能无限制新建线程,相互之间竞争,及可能占用过多系统资源导致死机或o ...

  7. Java线程的学习_线程池

    系统启动一个新线程需要很高的成本,因为它涉及与操作系统交互.在这种情况下,使用线程池可以很好地提高性能,尤其是当程序中需要创建大量生存期很短暂的线程时. 线程池在系统启动时即创建大量空闲的线程,程序将 ...

  8. JDK自带线程池学习

    JDK自带线程池 线程池的状态 线程有如下状态 RUNNING状态:Accept new tasks and process queued tasks SHUTDOWN状态:Don't accept ...

  9. 【温故而知新-万花筒】C# 异步编程 逆变 协变 委托 事件 事件参数 迭代 线程、多线程、线程池、后台线程

    额基本脱离了2.0 3.5的时代了.在.net 4.0+ 时代.一切都是辣么简单! 参考文档: http://www.cnblogs.com/linzheng/archive/2012/04/11/2 ...

随机推荐

  1. oc-18-继承

    //Animal.h #import <Foundation/Foundation.h> @interface Animal : NSObject { int _age; // 不写@pu ...

  2. 锁大全与 GDB调试

    1.innodb_lock_monitor:打开锁信息的方式 mysql> create table innodb_lock_monitor(id int) engine=InnoDB; Que ...

  3. DQS安装失败——系统重新引导是否处于挂起状态

    问题:         安装完SQL Server 2012后,准备安装DQS服务,但是总是提示:操作"检查系统重新引导是否处于挂起状态"已完成,但有错误,正在中止安装.非常无奈, ...

  4. Tcsh脚本编程

    Tcsh主要用于Free BSD等UNIX系统中. 一.输出字符串Hello的示例脚本 Tcsh脚本的基本格式.编写方法及脚本中使用的命令等,与Bash脚本完全相同,只需要直接套用即可. [root@ ...

  5. SquashFs工具制作

    下面是SquashFs.tar.gz的下载地址,解压后,直接执行其中的Makefile即可. SquashFs.tar.gz 说明: 制作squashfs格式的压缩镜像: ./mksquashfs . ...

  6. C# 自定义重绘TextBox

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.D ...

  7. c#基础--常量(const),只读字段(readonly)

    1.0:常量 常量被关键字const 所修饰 我们来看看常量的demo class Program { static void Main(string[] args) { const string n ...

  8. UIScrollView做循环图片

    #import "ViewController.h" #define IMAGE_COUNT 6 @interface ViewController () { UIImageVie ...

  9. nodejs 安装 postgresql module

    # npm -gd install node-gyp # export PATH=$PATH:/usr/local/pgsql/bin # npm -gd install pg for test: # ...

  10. LRU在MySQL缓存池的实现

    MySQL的InnoDB引擎设置有索引及数据缓存池,其中用到的LRU算法来维持缓存的命中率 这里用到了顺序表list来作为缓冲池,每个数据节点称为block 该算法采用“中点插入法”:当插入一个新bl ...