C++11的多线程并发编程(六)

C++11的多线程并发编程(六)–线程池

这篇主要记录线程池的写法,线程池就是有一堆已经创建好了的线程,初始都处于空闲等待状态,当有任务需要处理是,就从线程池中取一个空闲等待的线程来处理该仍无,等任务处理完毕后,就再次把线程放回池中,其实就是设置线程的状态,当线程池里的都处于忙碌状态,那么就根据需要创建一个新的线程,或者等待。

  1. threadPool.h
    头文件主要用来写任务类,定义任务类成员,以及成员函数,以及线程池管理类,定义线程数目,任务列表,线程入口函数,以及线程切换状态函数。
#ifndef _THREAD_POOL_H
#define _THREAD_POOL_H

#include <vector>
#include <iostream>
#include <string>
#include <pthread.h>

using namespace std;

//this class is for task excuting
class CTask
{
protected:
	string strTaskname;
	void *ptrData;

public:
	CTask() = default;
	CTask(string &taskName): strTaskname(taskName), ptrData(NULL){}
	virtual int Run() = 0;
	void setData(void* data);
		
	virtual ~CTask(){}	
};

class CThreadPool
{
private:
	static vector<CTask*> vecTasklist;
	static bool shutdown;
	int threadNum;
	pthread_t *pthread_id;
	
	static pthread_mutex_t pthreadMutex;
	static pthread_cond_t pthreadCond;

protected:
	static void *ThreadFunc(void *threadData);
	static int MoveToIdle(pthread_t tid);
	static int MoveToBusy(pthread_t tid);
	int Create();

public:
	CThreadPool(int threadNum);	
	int AddTask(CTask *task);
	int StopAll();
	int getTaskSize();
};

#endif

2.threadPool.cpp
主要用来设置成员初始化,定义线程成员函数,添加任务函数,创建线程函数,这里用的都是linux提供的POXIS的线程API,学习学习。

#include "threadPool.h"
#include <cstdio>
#include <iostream>

void CTask::setData(void *data)
{
	ptrData = data;
}

vector<CTask*> CThreadPool::vecTasklist;
bool CThreadPool::shutdown = false;
pthread_mutex_t CThreadPool::pthreadMutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t CThreadPool::pthreadCond = PTHREAD_COND_INITIALIZER;

CThreadPool::CThreadPool(int threadNums)
{
	this->threadNum = threadNums;
	cout << "I will create "<< threadNums << endl;
	Create();
}

void *CThreadPool::ThreadFunc(void *threadData)
{
	pthread_t tid = pthread_self();
	while(1)
	{
		pthread_mutex_lock(&pthreadMutex);
		while(vecTasklist.size() == 0 && !shutdown)
			pthread_cond_wait(&pthreadCond, &pthreadMutex);
		
		if(shutdown)
		{
			pthread_mutex_unlock(&pthreadMutex);
			printf("[tid: %lu]\texit\n", pthread_self());
			pthread_exit(NULL);
		}
	
		printf("[tid: %lu]\trun: ", tid);
		vector<CTask*>::iterator iter = vecTasklist.begin();
	
		CTask *task = *iter;
		if(iter != vecTasklist.end())
		{
			task = *iter;
			vecTasklist.erase(iter);
		}
		
		pthread_mutex_unlock(&pthreadMutex);
		
		task->Run();
		printf("[tid: %lu]\tidle\n", tid);
	}
	
	return (void*)0;
}

int CThreadPool::AddTask(CTask *task)
{
	pthread_mutex_lock(&pthreadMutex);
	vecTasklist.push_back(task);
	pthread_mutex_unlock(&pthreadMutex);
	
	pthread_cond_signal(&pthreadCond);
	
	return 0;
} 

int CThreadPool::Create()
{
	pthread_id = new pthread_t[threadNum];
	for(int i = 0; i < threadNum; i++)
		pthread_create(&pthread_id[i], NULL, ThreadFunc, NULL);
	
	return 0;
}

int CThreadPool::StopAll()
{
	if(shutdown)
		return -1;
	cout << "i will end all thread" << endl;
	
	shutdown = true;
	pthread_cond_broadcast(&pthreadCond);
	
	for (int i = 0; i < threadNum; i++)
		pthread_join(pthread_id[i], NULL);

	delete[] pthread_id;
	pthread_id = NULL;

	pthread_mutex_destroy(&pthreadMutex);
	pthread_cond_destroy(&pthreadCond);
	
	return 0;
}

int CThreadPool::getTaskSize()
{
	return vecTasklist.size();
}
  1. main.cpp
#include "threadPool.h"
#include <iostream>
#include <cstdio>
#include <stdlib.h>
#include <unistd.h>

class CMyTask : public CTask 
{
public:
	CMyTask() = default;
	int Run()
		{
			printf("%s\n", (char *)ptrData);
			int x = rand() % 4 + 1;
			sleep(x);
			return 0;
		}
	~CMyTask(){}
};

int main()
{
	CMyTask taskObj;
	char szTmp[] = "hello comedy";
	taskObj.setData((void*)szTmp);
	CThreadPool threadpool(5);
	
	for (int i = 0; i < 10; i++)
		threadpool.AddTask(&taskObj);
	
	while(1)
	{
		printf("There are still %d tasks need to handle\n",threadpool.getTaskSize());
		if(threadpool.getTaskSize()==0)
		{
			if(threadpool.StopAll() == -1)
			{
				printf("Thread pool clear, exit.\n");
				exit(0);
			}
		}	
		sleep(2);
		cout << "2 seconds later..." << endl;
	}
	return 0;
}

运行结果如图所示:
在这里插入图片描述

程序稳定运行,留着以后要用的时候参考。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值