Linux C++线程池

BaseTask.h 任务基类

 1 #ifndef MYTASK_H
 2 #define MYTASK_H
 3 #include "BaseTask.h"
 4
 5 class MyTask : public BaseTask
 6 {
 7 public:
 8     virtual void run(void);
 9 };
10
11 #endif

MyTask,h 其中一个实现的任务类

 1 #ifndef MYTASK_H
 2 #define MYTASK_H
 3 #include "BaseTask.h"
 4
 5 class MyTask : public BaseTask
 6 {
 7 public:
 8     virtual void run(void);
 9 };
10
11 #endif

MyTask.cpp

1 #include "MyTask.h"
2
3 void MyTask::run(void)
4 {
5     cout<<"Hello MyTask"<<endl;
6 }

Mutex.h 封装了的互斥类

 1 #ifndef MUTEX_H
 2 #define MUTEX_H
 3
 4 #include <iostream>
 5 #include <pthread.h>
 6 using namespace std;
 7
 8 class Mutex
 9 {
10 public:
11     Mutex();
12     void Lock();
13     void Unlock();
14
15 private:
16     pthread_mutex_t mutex;
17 };
18
19 #endif

Mutex.cpp

 1 #include "Mutex.h"
 2
 3 Mutex::Mutex()
 4 {
 5     pthread_mutex_init(&mutex,NULL);
 6 }
 7
 8 void Mutex::Lock()
 9 {
10     pthread_mutex_lock(&mutex);
11 }
12
13 void Mutex::Unlock()
14 {
15     pthread_mutex_unlock(&mutex);
16 }

MyThread.h 线程类

 1 #ifndef MYTHREAD_H
 2 #define MYTHREAD_H
 3
 4 #include <iostream>
 5 #include <pthread.h>
 6 #include <semaphore.h>
 7 #include "BaseTask.h"
 8
 9
10 // 前置定义
11 class MyThreadPool;
12
13 class MyThread
14 {
15 public:
16     MyThread(MyThreadPool* mtp);
17     void Set_Task(BaseTask* task);
18     void Start_Task();
19     /* 线程启动函数 必须写成静态成员函数 传入的参数为类对象自己*/
20     static void* Start_Func(void* arg);
21     /* 完成一个任务后 询问线程池管理器是否有未完成的任务*/
22     bool Fetch_Task();
23     /* 无更多任务 让自己进入线程池栈*/
24     void Recycle();
25 private:
26     /* 用于挂起线程 */
27     sem_t sem;
28     pthread_t tid;
29     BaseTask* task;
30     MyThreadPool* mtp;
31 };
32
33 #endif

MyThread.cpp

 1 #include "MyThreadPool.h"
 2 #include "MyThread.h"
 3
 4
 5 MyThread::MyThread(MyThreadPool* mtp)
 6 {
 7     sem_init(&sem,0,0);
 8     this->mtp = mtp;
 9     pthread_create(&tid,NULL,Start_Func,(void*)this);
10 }
11
12 void MyThread::Set_Task(BaseTask* task)
13 {
14     this->task = task;
15 }
16
17 void MyThread::Start_Task()
18 {
19     sem_post(&sem);
20 }
21
22 void* MyThread::Start_Func(void* arg)
23 {
24     MyThread* mt = (MyThread*) arg;
25     while(1)
26     {
27         sem_wait(&mt->sem);
28         mt->task->run();
29         if(mt->Fetch_Task())
30             mt->Start_Task();
31         else
32             mt->Recycle();
33     }
34 }
35
36 bool MyThread::Fetch_Task()
37 {
38     return mtp->FetchTask(this);
39 }
40
41 void MyThread::Recycle()
42 {
43     mtp->Recycle(this);
44 }

MyThreadPool.h 线程池类

 1 #ifndef MYTHREADPOOL_H
 2 #define MYTHREADPOOL_H
 3
 4 #include <iostream>
 5 #include <stack>
 6 #include <queue>
 7 #include "Mutex.h"
 8 #include "BaseTask.h"
 9
10 class MyThread;
11
12 class MyThreadPool
13 {
14 public:
15     /* no为要开辟的线程数目*/
16     MyThreadPool(int no);
17     /* 添加任务*/
18     void AddTask(BaseTask* task);
19     /* 供线程类调用 让线程类对象询问线程池任务队列中是否仍有任务未完成*/
20     bool FetchTask(MyThread* mt);
21     /* 回收线程 */
22     void Recycle(MyThread* mt);
23 private:
24     int no;
25     Mutex smutex;
26     Mutex qmutex;
27
28     stack<MyThread*> sthread;
29     queue<BaseTask*> qtask;
30 };
31
32 #endif

MyThreadPool.cpp

 1 #include "MyThreadPool.h"
 2 #include "MyThread.h"
 3
 4 MyThreadPool::MyThreadPool(int no)
 5 {
 6     this->no = no;
 7
 8     for(int i=0;i<no;++i)
 9     {
10         sthread.push(new MyThread(this));
11     }
12 }
13
14 void MyThreadPool::AddTask(BaseTask* task)
15 {
16     smutex.Lock();
17     if (!sthread.empty())
18     {
19         MyThread* mt = sthread.top();
20         sthread.pop();
21         smutex.Unlock();
22         mt->Set_Task(task);
23         mt->Start_Task();
24     }
25     else
26     {
27         smutex.Unlock();
28         qmutex.Lock();
29         qtask.push(task);
30         qmutex.Unlock();
31     }
32 }
33
34 bool MyThreadPool::FetchTask(MyThread* mt)
35 {
36     qmutex.Lock();
37     if (!qtask.empty())
38     {
39         mt->Set_Task(qtask.front());
40         qmutex.Unlock();
41         return true;
42     }
43     else
44     {
45         qmutex.Unlock();
46         return false;
47     }
48 }
49
50 void MyThreadPool::Recycle(MyThread* mt)
51 {
52     smutex.Lock();
53     sthread.push(mt);
54     smutex.Unlock();
55 }

main.cpp

 1 #include "MyThread.h"
 2 #include "MyThreadPool.h"
 3 #include "Mutex.h"
 4 #include "MyTask.h"
 5
 6 int main()
 7 {
 8     MyThreadPool mtp(3);
 9     while(1)
10     {
11         BaseTask* task = new MyTask;
12         mtp.AddTask(task);
13         sleep(5);
14         delete task;
15         task = NULL;
16     }
17 }

makefile

 1 pro: main.cpp libtp.a MyTask.cpp
 2     g++ -lpthread  main.cpp -L. -ltp MyTask.cpp -o pro
 3
 4 libtp.a: MyThreadPool.o MyThread.o Mutex.o
 5     ar cr libtp.a Mutex.o MyThreadPool.o MyThread.o
 6
 7 MyThread.o:MyThread.cpp
 8     g++ -c -lpthread MyThread.cpp -o MyThread.o
 9
10 MyThreadPool.o:MyThreadPool.cpp
11     g++ -c -lpthread MyThreadPool.cpp -o MyThreadPool.o
12
13 Mutex.o:Mutex.cpp
14     g++ -c -lpthread Mutex.cpp -o Mutex.o
15
16 clean:
17     rm libtp.a MyThreadPool.o Mutex.o MyThread.o pro

执行 ./pro 即可

编译: 我首先将线程类(MyThread.o) 互斥类(Mutex.o) 和 线程池类(MyThreadPool.o) 打包成一个静态库

静态库留出两个接口 一个是线程池的初始化 另外一个是用户自己继承BaseTask的run函数后 调用线程池的类对象 AddTask接口去增加任务

所以使用者只需自己指定要开辟的线程数(线程池的构造函数) 和 自定义 任务类对象即可使用这个线程池.

ps:所有文件都放在同一个目录下

时间: 2024-12-23 19:21:31

Linux C++线程池的相关文章

LINUX c++线程池框架

版权声明:原文地址及作者不详,如有侵权,请联系: 本文给出了一个通用的线程池框架,该框架将与线程执行相关的任务进行了高层次的抽象,使之与具体的执行任务无关.另外该线程池具有动态伸缩性,它能根据执行任务的轻重自动调整线程池中线程的数量.文章的最后,我们给出一个简单示例程序,通过该示例程序,我们会发现,通过该线程池框架执行多线程任务是多么的简单. 为什么需要线程池 目前的大多数网络服务器,包括Web服务器.Email服务器以及数据库服务器等都具有一个共同点,就是单位时间内必须处理数目巨大的连接请求,

Linux C++线程池实例

想做一个多线程服务器测试程序,因此参考了github的一些实例,然后自己动手写了类似来加深理解. 目前了解的线程池实现有2种思路: 第一种: 主进程创建一定数量的线程,并将其全部挂起,此时线程状态为idle,并将running态计数为0,等到任务可以执行了,就唤醒线程,此时线程状态为running,计数增加,如果计数达到最大线程数,就再创建一组空闲线程,等待新任务,上一组线程执行完退出,如此交替. 第二种: 采用生成者-消费者模式,主进程作为生成者,创建FIFO队列,在任务队列尾部添加任务,线程

Linux下线程池的理解与简单实现

首先,线程池是什么?顾名思义,就是把一堆开辟好的线程放在一个池子里统一管理,就是一个线程池. 其次,为什么要用线程池,难道来一个请求给它申请一个线程,请求处理完了释放线程不行么?也行,但是如果创建线程和销毁线程的时间比线程处理请求的时间长,而且请求很多的情况下,我们的CPU资源都浪费在了创建和销毁线程上了,所以这种方法的效率比较低,于是,我们可以将若干已经创建完成的线程放在一起统一管理,如果来了一个请求,我们从线程池中取出一个线程来处理,处理完了放回池内等待下一个任务,线程池的好处是避免了繁琐的

Linux简单线程池实现(带源码)

这里给个线程池的实现代码,里面带有个应用小例子,方便学习使用,代码 GCC 编译可用.参照代码看下面介绍的线程池原理跟容易接受,百度云下载链接: http://pan.baidu.com/s/1i3zMHDV 一.线程池简介 为什么使用线程池? 目前的大多数网络服务器,包括Web服务器.Email服务器以及数据库服务器等都具有一个共同点,就是单位时间内必须处理数目巨大的连接请求,但处理时间却相对较短. 传统多线程方案中我们采用的服务器模型则是一旦接受到请求之后,即创建一个新的线程,由该线程执行任

[转]简单Linux C线程池

转自:http://www.cnblogs.com/venow/archive/2012/11/22/2779667.html 贴原文章过来,提示有敏感词..那就不贴了. 以下为本博客作者注: 在threadpool_function函数中有这段代码, while ((pool->queue_cur_num == 0) && !pool->pool_close)   //队列为空时,就等待队列非空         {      pthread_cond_wait(&(p

谈一谈linux下线程池

什么是线程池: 首先,顾名思义,就是把一堆开辟好的线程放在一个池子里统一管理,就是一个线程池. 其次,为什么要用线程池,难道来一个请求给它申请一个线程,请求处理完了释放线程不行么?也行,但是如果创建线程和销毁线程的时间比线程处理请求的时间长,而且请求很多的情况下,我们的CPU资源都浪费在了创建和销毁线程上了,所以这种方法的效率比较低,于是,我们可以将若干已经创建完成的线程放在一起统一管理,如果来了一个请求,我们从线程池中取出一个线程来处理,处理完了放回池内等待下一个任务,线程池的好处是避免了繁琐

Linux下简单的多线程编程--线程池的实现

/* 写在前面的话: 今天刚“开原”,选择了一篇关于线程池的文件与大家分享,希望能对您学习有所帮助,也希望能与大家共同学习! 选择在这个特殊的时候注册并发文章也是有一些我个人特殊的意义的,看我的id(西游小学生.45)就知道了,哈哈.在这里也很感谢博客园的员工,刚发申请两分钟就同意了. */ 最近由于要写一个类似于QQ的程序,所以想到要用到多线程.既然要用多线程,那何不写一个线程池?于是上网搜了搜多线程的代码,发现大多都不是很完善,或者有些小bug.所以,在这里贴出一个完整的,经过我多重测试的,

Linux多线程实践(9) --简单线程池的设计与实现

线程池的技术背景 在面向对象编程中,创建和销毁对象是很费时间的,因为创建一个对象要获取内存资源或者其它更多资源.在Java中更是如此,虚拟机将试图跟踪每一个对象,以便能够在对象销毁后进行垃圾回收.所以提高服务程序效率的一个手段就是尽可能减少创建和销毁对象的次数,特别是一些很耗资源的对象创建和销毁.如何利用已有对象来服务(不止一个不同的任务)就是一个需要解决的关键问题,其实这就是一些"池化资源"技术产生的原因.比如大家所熟悉的数据库连接池正是遵循这一思想而产生的,本文将介绍的线程池技术同

linux下的线程池

什么时候需要创建线程池呢?简单的说,如果一个应用需要频繁的创建和销毁线程,而任务执行的时间又非常短,这样线程创建和销毁的带来的开销就不容忽视,这时也是线程池该出场的机会了.如果线程创建和销毁时间相比任务执行时间可以忽略不计,则没有必要使用线程池了. 下面是Linux系统下用C语言创建的一个线程池.线程池会维护一个任务链表(每个CThread_worker结构就是一个任务).   pool_init()函数预先创建好max_thread_num个线程,每个线程执thread_routine ()函