线程池是在处理高并发任务中有比较重要的价值,他的实现最基本原理就生产者和消费者模型,刚开始就开一定数量的线程,以程序中的某些功能模块为对象,以生产者与消费者模型为基本原理,不断使用这些固定数量的线程调度进行处理,避免了在高并发情况下,不断开辟线程造成的进程资源消耗.下面是一个简单的线程池程序,主要使用C++11中一些简单的新特性的最简单的线程池实现.
ThreadPool.h
#pragma once
#include <iostream>
#include<stdlib.h>
#include<thread>
#include<mutex>
#include<condition_variable>
#include<vector>
#include<functional>
#include<queue>
#define N 10
using namespace std;
class ThreadPool{
public:
//自定义void()的函数类型
typedef function<void()>Task;
ThreadPool();
~ThreadPool();
public:
size_t initnum;
//线程数组
vector<thread>threads ;
//任务队列
queue<Task>task ;
//互斥锁条件变量
mutex _mutex ;
condition_variable cond ;
//线程池工作结束时为真
bool done ;
//队列是否为空
bool isEmpty ;
//队列是否为满
bool isFull;
public:
void addTask(const Task&f);
void start(int num);
void setSize(int num);
void runTask();
void finish();
};
ThreadPool.cpp
#include"ThreadPool.h"
ThreadPool ::ThreadPool():done(false),isEmpty(true),isFull(false){
}
//设置池中初始线程数
void ThreadPool::setSize(int num){
(*this).initnum = num ;
}
//添加任务
void ThreadPool::addTask(const Task&f){
if(!done){
//保护共享资源
unique_lock<mutex>lk(_mutex);
//要是任务数量到了最大,就等待处理完再添加
while(isFull){
cond.wait(lk);
}
//给队列中添加任务
task.push(f);
if(task.size()==initnum)
isFull = true;
cout<<"Add a task"<<endl;
isEmpty = false ;
cond.notify_one();
}
}
void ThreadPool::finish(){
//线程池结束工作
for(size_t i =0 ;i<threads.size();i++){
threads[i].join() ;
}
}
void ThreadPool::runTask(){
//不断遍历队列,判断要是有任务的话,就执行
while(!done){
unique_lock<mutex>lk(_mutex);
//队列为空的话,就等待任务
while(isEmpty){
cond.wait(lk);
}
Task ta ;
//转移控制快,将左值引用转换为右值引用
ta = move(task.front());
task.pop();
if(task.empty()){
isEmpty = true ;
}
isFull =false ;
ta();
cond.notify_one();
}
}
void ThreadPool::start(int num){
setSize(num);
for(int i=0;i<num;i++){
threads.push_back(thread(&ThreadPool::runTask,this));
}
}
ThreadPool::~ThreadPool(){
}
Test.cpp
#include <iostream>
#include"ThreadPool.h"
void func(int i){
cout<<"task finish"<<"------>"<<i<<endl;
}
int main()
{
ThreadPool p ;
p.start(N);
int i=0;
while(1){
i++;
//调整线程之间cpu调度,可以去掉
this_thread::sleep_for(chrono::seconds(1));
auto task = bind(func,i);
p.addTask(task);
}
p.finish();
return 0;
}
简单的makefile
CC = g++
CXXFLAGS=-lpthread -g
target:Test.cpp ThreadPool.o
$(CC) Test.cpp ThreadPool.o -o Test $(CXXFLAGS)
ThreadPool.o:ThreadPool.cpp
$(CC) -c ThreadPool.cpp $(CXXFLAGS)
clean:
rm *.o
运行截图