emmmm,写这个的主要目的是为了加深对互斥锁和条件变量的理解,只看UNIX网络编程不实践一下老觉得心里没点底,正好这个东西能练一下而且面试好像也有问到,就手动实现了一下.
线程池运用的设计模式是命令模式,其原理基本上都能查到这里就不多说了.直接上代码好了.
首先是任务类 Task.h
#ifndef TASK_H
#define TASK_H
#include <string>
using namespace std;
class Task{
protected:
string name;
public:
virtual void run()=0;
void setname(string taskname);
};
#endif
Task.cc
#include "Task.h"
void Task::setname(string taskname){
name=taskname;
}
线程池管理类 Pthreadpoll.h
#ifndef PTHREADPOLL_H
#define PTHREADPOLL_H
#include <queue>
#include <pthread.h>
#include "Task.h"
using namespace std;
class Pthreadpoll{
private:
static queue<Task *>q;
static pthread_mutex_t mutex;
static pthread_cond_t cond;
static vector<pthread_t *>pthread_id;
static bool flag;
int size;
void create();
protected:
static void* threadfunc(void *args);
public:
Pthreadpoll(int s);
void addtask(Task *task);
int getsize();
void destroy();
~Pthreadpoll();
};
#endif
Pthreadpoll.cc
#include "Pthreadpoll.h"
#include <pthread.h>
#include <cstdio>
queue<Task *> Pthreadpoll::q;
pthread_mutex_t Pthreadpoll::mutex;
pthread_cond_t Pthreadpoll::cond;
vector<pthread_t *> Pthreadpoll::pthread_id;
bool Pthreadpoll::flag;
Pthreadpoll::Pthreadpoll(int s):size(s){
create();
}
void Pthreadpoll::create(){
pthread_t *id;
for(int i=0;i<size;i++){
id=new pthread_t;
pthread_id.push_back(id);
pthread_create(id,NULL,threadfunc,NULL);
}
}
void Pthreadpoll::addtask(Task *task){
bool dosignal;
pthread_mutex_lock(&mutex);
dosignal=(q.size()==0);
q.push(task);
pthread_mutex_unlock(&mutex);
if(dosignal)
pthread_cond_broadcast(&cond);
}
void* Pthreadpoll::threadfunc(void *args){
pthread_t tid=pthread_self();
while(1){
pthread_mutex_lock(&mutex);
while(!q.size()&&!flag)
pthread_cond_wait(&cond,&mutex);
if(flag){
pthread_mutex_unlock(&mutex);
pthread_exit(NULL);
}
Task *task=q.front();
q.pop();
printf("tid=%lu ",tid);
task->run();
delete task;
pthread_mutex_unlock(&mutex);
}
return NULL;
}
int Pthreadpoll::getsize(){
return q.size();
}
Pthreadpoll::~Pthreadpoll(){
destroy();
}
void Pthreadpoll::destroy(){
flag=true;
pthread_cond_broadcast(&cond);
for(int i=0;i<size;i++){
pthread_join(*(pthread_id[i]),NULL);
delete pthread_id[i];
}
}
主函数 main.cc
#include "Pthreadpoll.h"
#include <string>
#include <iostream>
#include <cstdio>
using namespace std;
class Texttask:public Task{
public:
virtual void run(){
cout<<name<<",mission complete!"<<endl;
}
};
int main(){
string name="hello";
Pthreadpoll pthreadpoll(4);
for(int i=0;i<10;i++){
Task *task=new Texttask;
task->setname(name);
pthreadpoll.addtask(task);
}
while(1){
if(!pthreadpoll.getsize())
break;
}
printf("success\n");
}
makefile
objects=Task.o Pthreadpoll.o main.o
pthreadpoll.out:$(objects)
g++ -o pthreadpoll.out $(objects) -lpthread
main.o:main.cc Pthreadpoll.o Task.o
g++ -g -c main.cc
Pthreadpoll.o:Pthreadpoll.cc Pthreadpoll.h Task.o
g++ -g -c Pthreadpoll.cc
Task.o:Task.cc Task.h
g++ -g -c Task.cc
.PHONE:clean
clean:
rm pthreadpoll.out $(objects)
其中的实现参考过挺多文章的,然后锁和互斥变量的运用我是仔细阅读过UNIX网络编程的,其中的dosignal变量参照了书上的实现,虽然其他博客大多没有这么写,但是这个地方我觉得书上写的还是很精辟的.强烈推荐看下这本书.当然博主的代码可能还有纰漏,我只测试过这个样例,欢迎指出错误,谢谢.