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 <= ) 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库实现线程池学习及线程实现的异步调用的更多相关文章
- 【Java多线程】线程池学习
Java线程池学习 众所周知,Java不仅提供了线程,也提供了线程池库给我们使用,那么今天来学学线程池的具体使用以及线程池基本实现原理分析. ThreadPoolExecutor ThreadPool ...
- Java线程池学习
Java线程池学习 Executor框架简介 在Java 5之后,并发编程引入了一堆新的启动.调度和管理线程的API.Executor框架便是Java 5中引入的,其内部使用了线程池机制,它在java ...
- Java线程池学习总结
一 使用线程池的好处 池化技术相比大家已经屡见不鲜了,线程池.数据库连接池.Http 连接池等等都是对这个思想的应用.池化技术的思想主要是为了减少每次获取资源的消耗,提高对资源的利用率. 线程池提供了 ...
- android中的线程池学习笔记
阅读书籍: Android开发艺术探索 Android开发进阶从小工到专家 对线程池原理的简单理解: 创建多个线程并且进行管理,提交的任务会被线程池指派给其中的线程进行执行,通过线程池的统一调度和管理 ...
- Java 线程池学习
Java里面线程池的顶级接口是Executor,但是严格意义上讲Executor并不是一个线程池,而只是一个执行线程的工具.真正的线程池接口是ExecutorService. 下面这张图完整描述了线程 ...
- Java线程池学习心得
一.普通线程和线程池的对比 new Thread的弊端如下: a. 每次new Thread新建对象性能差.b. 线程缺乏统一管理,可能无限制新建线程,相互之间竞争,及可能占用过多系统资源导致死机或o ...
- Java线程的学习_线程池
系统启动一个新线程需要很高的成本,因为它涉及与操作系统交互.在这种情况下,使用线程池可以很好地提高性能,尤其是当程序中需要创建大量生存期很短暂的线程时. 线程池在系统启动时即创建大量空闲的线程,程序将 ...
- JDK自带线程池学习
JDK自带线程池 线程池的状态 线程有如下状态 RUNNING状态:Accept new tasks and process queued tasks SHUTDOWN状态:Don't accept ...
- 【温故而知新-万花筒】C# 异步编程 逆变 协变 委托 事件 事件参数 迭代 线程、多线程、线程池、后台线程
额基本脱离了2.0 3.5的时代了.在.net 4.0+ 时代.一切都是辣么简单! 参考文档: http://www.cnblogs.com/linzheng/archive/2012/04/11/2 ...
随机推荐
- /proc/sys/vm/ 内存参数
linux下proc里关于磁盘性能的参数 http://blog.csdn.net/eroswang/article/details/6126646 我们在磁盘写操作持续繁忙的服务器上曾经碰到一个特 ...
- Spark SQL - DataFrame
1 Overview Spark SQL is a Spark module for structured data processing. It provides a programming abs ...
- Golang学习 - unicode 包
------------------------------------------------------------ const ( MaxRune = '\U0010FFFF' // Unico ...
- Linux清除磁盘上的RAID信息
我的笔记本是DELL的Inspiron 14z,原装存储器是由32G的固态硬盘和512G的机器硬盘组成.后来我自己又给它加了一个256G的固态硬盘,装并装上了CentOS,打算把500G的机械硬盘当资 ...
- 1.6 Indexing and Basic Data Operations--目录
1.6.1 什么是 Indexing 1.6.2 Uploading Data with Index Handlers 1.6.3 Uploading Data with Solr Cell usin ...
- Android 珍藏(二)
一.如何控制Android LED等?(设置NotificationManager的一些参数) 代码如下: final int ID_LED=19871103; NotificationManage ...
- 《算法导论》习题解答 Chapter 22.1-3(转置图)
一.邻接表实现 思路:一边遍历,一边倒置边,并添加到新的图中 邻接表实现伪代码: for each u 属于 Vertex for v 属于 Adj[u] Adj1[v].insert(u); 复杂度 ...
- asp.net中Response对象鱼Request对象
在asp.net中Response与Request对象是两个常用的对象,虽然他们长得有点像,但是作用却是截然不同,我们来看一下他们他们都有哪些不同. 一.Response对象主要作用:像浏览器输出信息 ...
- Oracle 基础 游标
一:游标的基本原理 游标用来处理从数据库中检索的多行记录(使用SELECT语句).利用游标,程序可以逐个地处理和遍历一次检索返回的整个记录集. 为了处理SQL语句,Oracle将在内存中分配一个区域, ...
- StdRandom.java
/************************************************************************* * Compilation: javac StdR ...