Linux 之C++ 线程池
来源:互联网 发布:鬼王漫画网络班 编辑:程序博客网 时间:2024/06/11 23:11
我想做的就是对每个线程进行有针对性的控制,也即可以对线程进行暂停,恢复,退出等等精细控制,对于此项要求,我的想法是声明一个类,该类中有些精细的操作其中包括该线程的状态,对线程控制的互斥变量(pthread_mutex_t),以及唤醒的条件(pthread_cond_t),要实现这些功能其核心在于,每个线程拥有自己的控制变量,也即线程执行函数是线程类的静态函数,该线程函数的参数是该线程类对象的this指针!!!
class Servant{private:pthread_mutex_t mutex_x;pthread_cond_t cond_t;int state;public:pthread_t m_tid;Servant();void start();static void* ThreadProc(void* data);void notify();void stop();void wakeup();void exit();void join();};这是该线程类的声明,最主要的是查看ThreadProc静态函数
void* Servant::ThreadProc(void* data){ Servant* ser=(Servant*)data; int result=0; while(ser->state!=EXIT) { while(ser->state==IDLE) { result=pthread_mutex_lock(&(ser->mutex_x)); if(0==result) { printf("waiting for the mutex \n"); } result=pthread_cond_wait(&(ser->cond_t),&(ser->mutex_x)); if(ser->state!=IDLE) goto End; printf("the conditions has been notified\n"); //we take this thread to busy list ser->m_pool->AddtoIdle(false,ser); ser->m_pool->Addtobusy(true,ser); // really work DoSomething: ser->state=WORKING; printf("Do Something...\n"); ser->DoJob(); ser->Complete();//this function change state End: pthread_mutex_unlock(&(ser->mutex_x)); } } return NULL;}这函数,主要控制的就两项,其一state,每次对线程状态的改变,都是基于原子线程已经执行完毕的基础上的,也即,核心操作是不能被状态的改变所修改的。每次被唤醒时,都需要进行检测state的值,如果STATE还是RUN,则表明有新的任务要处理,否则表明唤醒只是为了要修改当前线程状态!!!,现在看一下一个API
pthread_cond_wait,该函数调用时首先必须必须由本线程加锁,这个函数需要两个变量一个是mutex_x(加锁的互斥变量)和cond_t(条件变量),在更新条件以前,mutex_x一直保持锁定状态,并在线程挂起进入等待解锁,当执行pthread_cond_singal时,激活互斥变量mutex,并向下执行,当离开pthread_cond_wait时,重新加锁
现Servant.h文件内容如下:
#include<pthread.h>#include<vector>using namespace std;class Servant{private:pthread_mutex_t mutex_x;pthread_cond_t cond_t;int state;public:pthread_t m_tid;Servant();void start();static void* ThreadProc(void* data);void notify();void stop();void wakeup();void exit();void join();};//ServantPool supposed to be singltonclass ServantPool{private:vector<Servant*> m_idle_list;vector<Servant*> m_busy_list;ServantPool(){};static ServantPool * hInstance;public:void TerminateAll();void create(int num);void start();void stop(pthread_t id);void wakeup(pthread_t id);void waitforAll();~ServantPool();static ServantPool * getInstance();};
Servant.cpp文件内容如下:
#include<stdio.h>#include<stdlib.h>#include<string.h>#include<errno.h>#include<netinet/in.h>#include<arpa/inet.h>#include<unistd.h>#include"Servant.h"#define WORKING 1#define STOP 2#define EXIT 3#define IDLE 4static int num=0;static pthread_mutex_t vec_mutex; void Servant::start(){ state=IDLE; int result=pthread_create(&m_tid,NULL,ThreadProc,this); if(0!=result) { printf("thread create result :%s\n",strerror(errno)); }}Servant::Servant(ServantPool* ma){ thread_id=num++; m_pool=ma; pthread_mutex_init(&mutex_x,NULL); pthread_cond_init(&cond_t,NULL); }void Servant::setSocket(int m){ m_socket=m;}void Servant::DoJob(){ char buf[100]={0}; recv(m_socket,buf,100,0); printf("we haved the %d recv:%s\n",num++,buf); close(m_socket);}void* Servant::ThreadProc(void* data){ Servant* ser=(Servant*)data; int result=0; while(ser->state!=EXIT) { while(ser->state==IDLE) { result=pthread_mutex_lock(&(ser->mutex_x)); if(0==result) { printf("waiting for the mutex \n"); } result=pthread_cond_wait(&(ser->cond_t),&(ser->mutex_x)); if(ser->state!=IDLE) goto End; printf("the conditions has been notified\n"); //we take this thread to busy list ser->m_pool->AddtoIdle(false,ser); ser->m_pool->Addtobusy(true,ser); // really work DoSomething: ser->state=WORKING; printf("Do Something...\n"); ser->DoJob(); ser->Complete();//this function change state End: pthread_mutex_unlock(&(ser->mutex_x)); } } return NULL;}void Servant::stop(){ if(state==IDLE) { m_pool->AddtoIdle(false,this); m_pool->Addtostop(true,this); state=STOP; printf("thread stop!\n"); } else if(state==WORKING) { printf("current state is WORKING stop failed!\n"); } else if(state==STOP) { printf("thread already stopped!\n"); } else { printf("sorry unknown state!\n"); state=STOP; }}void Servant::wakeup(){ if(state==STOP) { m_pool->Addtostop(false,this); m_pool->AddtoIdle(true,this); state=IDLE; printf("thread wakeup!\n"); } else if(state==WORKING) { printf("current state is WORKING stop failed!\n"); } else if(state==IDLE) { printf("current state is idle never need wakeup!\n"); } else { printf("sorry unknown state..\n"); state=IDLE; }}void Servant::Complete()//完成操作{ //完成任务,该线程变为idle m_pool->Addtobusy(false,this); m_pool->AddtoIdle(true,this); state=IDLE;}void Servant::join(){ pthread_join(m_tid,NULL);}void Servant::notify(){ if(state==IDLE) { printf("we have notified thread running\n"); pthread_cond_signal(&cond_t); } else { printf("sorry ,the signal is not correct\n"); }}void Servant::exit(){ state=EXIT; pthread_cond_signal(&cond_t); }void ServantPool::StopAll(){ vector<Servant*>::iterator itr=m_idle_list.begin(); for(;itr!=m_idle_list.end();) { (*itr)->stop(); } itr=m_busy_list.begin(); for(;itr!=m_busy_list.end();) { (*itr)->stop(); } }void ServantPool::create(int num){ int i=0; for(;i<num;i++) { Servant* tmp=new Servant(this); m_idle_list.push_back(tmp); }}void ServantPool::AddtoIdle(bool add,Servant* ser){ if(add) { // add ser to idle list pthread_mutex_lock(&vec_mutex); m_idle_list.push_back(ser); pthread_mutex_unlock(&vec_mutex); } else { // del ser from idle list pthread_mutex_lock(&vec_mutex); vector<Servant*>::iterator itr=m_idle_list.begin(); for(;itr!=m_idle_list.end();itr++) { if(*itr==ser) { m_idle_list.erase(itr); break; } } pthread_mutex_unlock(&vec_mutex); }}void ServantPool::Addtobusy(bool add,Servant* ser){ if(add) { // add ser to idle list pthread_mutex_lock(&vec_mutex); m_busy_list.push_back(ser); pthread_mutex_unlock(&vec_mutex); } else { // del ser from idle list pthread_mutex_lock(&vec_mutex); vector<Servant*>::iterator itr=m_busy_list.begin(); for(;itr!=m_busy_list.end();itr++) { if(*itr==ser) { m_busy_list.erase(itr); break; } } pthread_mutex_unlock(&vec_mutex); }}void ServantPool::Addtostop(bool add,Servant* ser){ if(add) { // add ser to idle list pthread_mutex_lock(&vec_mutex); m_stop_list.push_back(ser); pthread_mutex_unlock(&vec_mutex); } else { // del ser from idle list pthread_mutex_lock(&vec_mutex); vector<Servant*>::iterator itr=m_stop_list.begin(); for(;itr!=m_stop_list.end();itr++) { if(*itr==ser) { m_stop_list.erase(itr); break; } } pthread_mutex_unlock(&vec_mutex); }}void ServantPool::startAll(){ int i=0; for(;i<m_idle_list.size();i++) { Servant* tmp=m_idle_list[i]; printf("start the thread %d\n",i); tmp->start();//create the thread }}void ServantPool::stop(Servant* id){ vector<Servant*>::iterator itr=m_idle_list.begin(); for(;itr!=m_idle_list.end();itr++) { if((*itr)==id) { (*itr)->stop(); return; } }}void ServantPool::waitforAll(){ int i=0; int nums=m_busy_list.size(); for(;i<nums;i++) { Servant* tmp=m_busy_list[i]; tmp->join(); } nums=m_idle_list.size(); i=0; for(;i<nums;i++) { Servant* tmp=m_idle_list[i]; tmp->join(); } }void ServantPool::wakeup(Servant* id){ vector<Servant*>::iterator itr=m_busy_list.begin(); for(;itr!=m_busy_list.end();itr++) { if((*itr)==id) { (*itr)->wakeup(); return; } }}ServantPool * ServantPool::hInstance=NULL;ServantPool * ServantPool::getInstance(){ if(NULL==hInstance) { hInstance=new ServantPool(); pthread_mutex_init(&vec_mutex,NULL); } return hInstance; }ServantPool::~ServantPool(){ vector<Servant*>::iterator itr=m_idle_list.begin(); for(;itr!=m_idle_list.end();) { (*itr)->exit(); delete *itr; itr=m_idle_list.erase(itr); } itr=m_busy_list.begin(); for(;itr!=m_busy_list.end();) { (*itr)->exit(); delete *itr; itr=m_busy_list.erase(itr); } itr=m_stop_list.begin(); for(;itr!=m_stop_list.end();) { (*itr)->exit(); delete *itr; itr=m_stop_list.erase(itr); } }Servant* ServantPool::Accepting(){ if(m_idle_list.size()>0) { return m_idle_list[0]; } return NULL;}
main.c文件如下:
#include<stdio.h>#include<string.h>#include<stdlib.h>#include<pthread.h>#include"Servant.h"//create 100 servants thread#define SERVANT_NUM 1int main(){ServantPool *mm=ServantPool::getInstance();printf("we begin create %d Servant threads \n",SERVANT_NUM);mm->create(SERVANT_NUM);mm->start();mm->waitforAll();return 0;}
makefile文件内容如下:
test:Servant.o main.og++ -o test Servant.o main.o -lpthreadServant.o:Servant.cpp Servant.hg++ -g -c Servant.cpp -lpthreadmain.o:main.c Servant.h g++ -g -c main.c -lpthreadclean:rm *.o test
这里面需要注意一点,就是,在修改线程状态时,首先应该修改的是线程状态值,然后才继续进行信号通知,这样可以避免,当信号通知时,状态值还没有发生变化!!!
信号修改失败。好了,这就是暂时要表达的线程池的内容了,如有错误,该请大神指正
0 0
- {linux C}之linux下的C线程池
- linux c线程池
- Linux C线程池
- Linux C 线程池
- linux c 线程池
- Linux C 线程池
- linux c/c++网络编程之—线程池模型
- 高效线程池之无锁化实现(Linux C)
- Linux下c开发 之 线程通信
- Linux下c开发之线程通信
- Linux下c开发 之 线程通信
- Linux下c开发 之 线程通信
- Linux下c开发 之 线程通信
- Linux下c开发 之 线程通信
- Linux下c开发 之 线程通信
- Linux下c开发 之 线程通信
- Linux下c开发 之 线程通信
- linux c学习之线程控制
- 01背包问题
- PHP使用存储过程
- Builder模式和Prototype模式-都有面向接口基类
- FZU 1969 && UVA 11426 GCD Extreme (欧拉函数 或 莫比乌斯反演)
- Java中可变长参数的使用及注意事项
- Linux 之C++ 线程池
- Delphi XE 5 移动开发入门手册(完整版)
- Android进阶(二十)AndroidAPP开发问题汇总(四)
- window多线程及同步实现
- 磁盘读写和数据库读写哪个更好?磁盘读写与数据库的关系
- 关于cvx库的license激活问题详解
- iOS开发——改变UITextField的样式:占位符颜色、字符起始位置等
- 毕业俩个月的总结---------------------写给自己
- [Java Core]Java类的equals方法的实现