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. error C2440:“类型转换":无法从“void (__thiscall Play1::* )(int *)”转换为“cocos2d::SEL_CallFucN

    转自:http://zhidao.baidu.com/link?url=VfSSkA0xfTVwNKaKh4tqW_sXlcsK-Rb16nEtQw5zaq5_306lnwJN3Kdb-rFp-r4L ...

  2. ext2文件系统

    2.1. 总体存储布局 我们知道,一个磁盘可以划分成多个分区,每个分区必须先用格式化工具(例如某种mkfs命令)格式化成某种格式的文件系统,然后才能存储文件,格式化的过程会在磁盘上写一些管理存储布局的 ...

  3. 异常处理之namespace找不到

    最近在做控件的时候遇到了这么一个异常 就是说类库中明明就有命名空间,但是在winForm中引用的时候也能正常显示, 可是编译的时候却报 找不到指定的命名空间 这样的异常,头痛了好久,结果看到了winF ...

  4. SimpleUrlHandlerMapping 处理器映射的配置--转

    http://blog.csdn.net/rainier001/article/details/6860491 <?xml version="1.0" encoding=&q ...

  5. linux设备驱动之select

    转载:http://blog.csdn.net/mo_hui123456/article/details/7961619 select系统调用用于多路监控,为什么称为多路呢,它可监控多个文件,例如我监 ...

  6. Design Mode 之 行为模式

    行为型模式,共十一种:策略模式.模板方法模式.观察者模式.迭代子模式.责任链模式.命令模式.备忘录模式.状态模式.访问者模式.中介者模式.解释器模式. 看看这11中模式的关系,大致可分为四类:(1) ...

  7. Guid vs Int

    http://www.uml.org.cn/net/200512283.htm http://www.cnblogs.com/twodays/archive/2004/07/19/25562.aspx ...

  8. 【python调用windows CLI】调用adb统计Android app的流量消耗

    主要记录python如何调用windows CLI 手机连接PC,adb devices可以看到手机sn 通过adb 获取指定app的processID UID 读取Android  /proc/ne ...

  9. 安卓Design包之CoordinatorLayout配合AppBarLayout,ToolBar,TabLaout的使用

    转载: CoordinatorLayout配合AppBarLayout,Toolbar和TabLayout的使用 控件的简单介绍: AppBarLayout:它是继承LinerLayout实现的一个V ...

  10. jQuery全选与反选,且解决点击只执行一次的问题

    <html> <head> <script src="jquery-1.11.1.min.js" type="text/javascript ...