线程池的c++实现

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变量参照了书上的实现,虽然其他博客大多没有这么写,但是这个地方我觉得书上写的还是很精辟的.强烈推荐看下这本书.当然博主的代码可能还有纰漏,我只测试过这个样例,欢迎指出错误,谢谢.

猜你喜欢

转载自blog.csdn.net/qq_34262582/article/details/80343567