Linux C++线程池
这是对pthread线程的一个简单应用
1. 实现了线程池的概念,线程可以重复使用。
2. 对信号量,互斥锁等进行封装,业务处理函数中只需写和业务相关的代码。
3. 移植性好。如果想把这个线程池代码应用到自己的实现中去,只要写自己的业务处理函数和改写工作队列数据的处理方法就可以了。
Sample代码主要包括一个主程序和两个线程实现类
ThreadTest.cpp:主程序
CThreadManager:线程管理Class,线程池的实现类
CThread:线程Class.
主程序实现方法。
1. 实现main函数和一个需要线程处理的业务函数(例子代码中业务函数是一个简单的计算函数Count)。在main函数中创建CThreadManager的实例,产生线程池。这个时候,把业务函数作为函数指针传到CThreadManager里面,最终会被线程调用。
2. 向工作队列中放入业务函数要处理的数据。
3. 设置信号量,唤醒线程。
CODE:
1 // 线程要执行的函数
2 int Count(int nWork)
3 {
4 int nResult = nWork * nWork;
5 printf("count result is %d\n",nResult);
6
7 return 0;
8 }
9
10 int main() {
11
12 // 创建线程管理类的实例,把要执行的线程函数和最大线程数传进去
13 CThreadManager* pManager = new CThreadManager(Count, 3);
14
15 // 把要进行计算的数放到工作队列中
16 pManager->PushWorkQue(5);
17 pManager->PushWorkQue(20);
18
19 // 设置信号量,唤醒线程
20 pManager->PostSem();
21 pManager->PostSem();
22
23 // 等待子线程执行
24 sleep(1);
25
26 return 0;
27 }
CThreadManager实现的方法
1. 把信号量和互斥锁等封装成自己的函数
2. 在new方法里,循环调用CThread的new方法,启动一定数量(可设定)的线程,产生线程池。
3. 这些线程启动后,就会执行CThreadManager中的ManageFuction函数。这个函数是无限循环的,保证了线程在整个程序的生命周期中不销毁。
4. 在循环处理里面,第一行代码就是等待一个信号量,这个信号量是由主程序进行设置的,这个信号信号量如果没有被设置(代表暂时没有需要处理的工作),所有线程都在这里阻塞着。
4. 一旦信号量被设置,根据Linux线程调度机制,在阻塞的线程队列中,其中一个线程被唤醒,可以执行后面的代码。
5. 从工作队列中取出要进行处理的数据(使用互斥锁进行排他)
6. 通过函数指针调用main函数传过来的业务函数,处理数据。
7. 业务函数执行完之后,线程进入下一个循环,等待新的信号量。
class CThreadManager {
friend void* ManageFuction(void*);
private:
sem_t m_sem; // 信号量
pthread_mutex_t m_mutex; // 互斥锁
queue<int> m_queWork; // 工作队列
list<CThread*> m_lstThread; // 线程list
int (*m_threadFuction)(int); //函数指针,指向main函数传过来的线程执行函数
public:
CThreadManager(int (*threadFuction)(int), int nMaxThreadCnt);
virtual ~CThreadManager();
int WaitSem();
int PostSem();
int LockMutex();
int UnlockMutex();
void PushWorkQue(int nWork);
int PopWorkQue();
int RunThreadFunction(int nWork);
};
// 线程执行函数,它只是个壳子,处理信号量和互斥锁等,
// 最后调用main函数传过来的线程执行函数来实现业务处理
void* ManageFuction(void* argv)
{
CThreadManager* pManager = (CThreadManager*)argv;
// 进行无限循环(意味着线程是不销毁的,重复利用)
while(true)
{
// 线程开启后,就在这里阻塞着,直到main函数设置了信号量
pManager->WaitSem();
printf("thread wakeup.\n");
// 从工作队列中取出要处理的数
pManager->LockMutex();
int nWork = pManager->PopWorkQue();
pManager->UnlockMutex();
printf("call Count function.\n");
pManager->RunThreadFunction(nWork);
}
return 0;
}
CThreadManager::CThreadManager(int (*threadFuction)(int), int nMaxThreadCnt)
sem_init(&m_sem, 0, 0);
pthread_mutex_init(&m_mutex, NULL);
m_threadFuction = threadFuction;
for(int i=0; i<nMaxThreadCnt; i++)
{
CThread* pThread = new CThread(ManageFuction, this);
printf("thread started.\n");
m_lstThread.push_back(pThread);
}
}
CThread实现的方法
CThreadManager比较简单,封装了创建线程和join线程的函数。
CThread::CThread(void* (*threadFuction)(void*),void* threadArgv)
// 初始化线程属性
pthread_attr_t threadAttr;
pthread_attr_init(&threadAttr);
pthread_create(&m_thread, &threadAttr, threadFuction, threadArgv);
}
Linux C++线程池相关推荐
- linux下线程池实现
linux下线程池实现 转自:http://blog.csdn.net/lmh12506/article/details/7753952 前段时间在github上开了个库,准备实现自己的线程池的,因为 ...
- linux动态线程池--原理,这儿的代码不完整
本文给出了一个通用的线程池框架,该框架将与线程执行相关的任务进行了高层次的抽象,使之与具体的执行任务无关.另外该线程池具有动态伸缩性,它能根据执行任务的轻重自动调整线程池中线程的数量.文章的最后,我们 ...
- linux nginx线程池,nginx使用线程池提升9倍性能
众所周知nginx使用异步,事件驱动方法处理连接.这意味着nginx使用一个worker进程处理多个连接和请求,而不是每一个请求有一个专门的进程或着线程处理(像传统架构的服务器那样,例如apache) ...
- linux posix 线程池_linux多线程--POSIX Threads Programming
linux多线程自己从接触很久也有不少实践,但总是觉得理解不够深刻,不够系统.借这篇文章试着再次系统学习一下linux多线程编程,理解编程的concept,细致看一下POSIX pthread API ...
- linux c++线程池的实现
http://blog.csdn.net/zhoubl668/article/details/8927090?t=1473221020107 线程池的原理大家都知道,直接上代码了^_^ Thread. ...
- Linux C++线程池实例
http://www.cnblogs.com/danxi/p/6636095.html 想做一个多线程服务器测试程序,因此参考了github的一些实例,然后自己动手写了类似的代码来加深理解. 目前了解 ...
- linux 下线程池
基本想法是这样的: 1.预创建的线程通过mutex休眠在线程池中.这样,通过unlock该mutex就可以唤醒该线程了: 2.出于简单性的目标,一个线程池内的所有线程的属性都是 ...
- 简单实现Linux下线程池
最近在Linux下使用mysql时有时会报查询异常,看网上解决方案是多次并发使用,通过gdb调试也找到问题,主要是上次查询结果集未释放,最终导致如此. 大佬说根本解决方案还是线程池,就去看了线程池的一 ...
- 简单Linux C线程池
大多数的网络服务器,包括Web服务器都具有一个特点,就是单位时间内必须处理数目巨大的连接请求,但是处理时间却是比较短的.在传统的多线程服务器模型中是这样实现的:一旦有个请求到达,就创建一个新的线程,由 ...
最新文章
- python3.5和pip3安装路径不匹配问题
- CoreData 从入门到精通(四)并发操作
- linux上安装telnet服务器:linux vmvare虚拟机 安装telnet redhat9
- linux 运行eclipse,解决Linux下Eclipse启动错误
- 信息学奥赛C++语言:推销产品
- Python读取dat文件数据并构成Dataframe对象
- 七.激光SLAM框架学习之A-LOAM框架---速腾Robosense-16线雷达室内建图
- 美国“加强软件供应链安全实践的指南” (SSDF V1.1草案) 解读来了
- html5标题居中怎么设置,标题居中怎么设置
- 致此刻选专业发愁的你 | 从学技术到做CEO:电子信息类专业在大学时期的正确打怪升级路径
- mysql语句大小写要求_mysql踩坑(一)-大小写规则
- Android 安装apk流程,Android PMS(二)-Apk安装流程
- 你做的数据运营,90%都是无用功
- Bert使用之一_基本使用
- 计算机二级试题及答案百度云链接,计算机二级Photoshop题库及答案
- 7-14 十六进制转十进制 7-15 十进制转十六进制
- CSS3新增属性——过渡和动画(2D属性,3D动画)
- 常见的加密算法分类及介绍
- 进制选择器c语言算法,c語言编程技巧第1章走进Delph.doc
- 离散数学,生成元,元素的阶