线程池其实就是一堆处理任务的线程和 一个任务队列 ,处理线程不断地从这个任务队列中拿出任务进行处理。
不过需要注意的是 对于这个任务队列需要保证线程安全
一个简易的线程池需要
1,一个向任务队列中添加任务的接口
2,一个从任务队列中取出任务的接口
3,一个处理任务的方法;
4,提前创建一批线程
线程安全的任务队列使用信号量和互斥锁来实现
1.创建线程
void start(int threadCount);
循环创建 threadcount 个线程
绑定处理任务的方法
2.添加任务的接口
向任务队列中添加任务 ,添加完成之后唤醒一个线程
3.从队列中取出任务
判断当队列中元素个数为0的时候使用wait方法,阻塞线程
如果元素个数不为0,获取一个任务,将这个任务移除队列,线程处理任务。
完整代码
#ifndef MYTHREADPOOL_H
#define MYTHREADPOOL_H
#include<functional>
#include<vector>
#include<thread>
#include<queue>
#include<condition_variable>
#include<mutex>
#include<iostream>
using namespace std;
class MyThreadPool {
public:
//定义一个void类型的函数类型
typedef std::function<void()> Task;
~MyThreadPool();
static MyThreadPool* GetInstance();
//启动线程池,线程池进入等待状态
void start(int thread_count);
//关闭线程池,如果没有任务了就直接推出所有线程,如果有则等待完成后全部推出
void stop();
//添加一个任务
void addTask(const Task& ta);
private:
MyThreadPool();
void runTask();
Task takeTask();
vector<thread>m_threads;//线程
queue<Task>m_taskqueue;//任务队列
condition_variable m_cond;//条件变量
mutex m_mutex;//互斥锁
mutex m_con_mutex;
int m_thread_count;//线程数
int max_task;
bool over;//是否退出
};
#include"MyThreadPool.h"
#include<Windows.h>
MyThreadPool::MyThreadPool() {
over = false;
}
MyThreadPool::~MyThreadPool() {
}
MyThreadPool* MyThreadPool::GetInstance()
{
static MyThreadPool instance;
return &instance;
}
void MyThreadPool::start(int threadCount) {
m_thread_count = threadCount;
over = false;
for (int i = 0; i < m_thread_count; ++i) {
m_threads.push_back(thread(&MyThreadPool::runTask, this));
m_threads[i].detach();
}
}
void MyThreadPool::stop(){
unique_lock<mutex> lck(m_mutex);
over = true;
m_cond.notify_all();
for (int i = 0; i < m_thread_count; ++i)
{
m_threads[i].detach();
}
m_threads.clear();
}
void MyThreadPool::addTask(const Task& task) {
unique_lock<mutex> lck(m_mutex);
m_taskqueue.push(task);
m_cond.notify_one();
}
void MyThreadPool::runTask() {
unique_lock<mutex> lck(m_con_mutex);
while (!over || !m_taskqueue.empty()) {
Task task = takeTask();
if (task)
{
std::cout << "任务队列大小:" << m_taskqueue.size() << "线程id" << this_thread::get_id() << endl;
task();
}
}
}
MyThreadPool::Task MyThreadPool::takeTask() {
unique_lock<mutex> lck(m_mutex);
while (m_taskqueue.empty() && !over) {
m_cond.wait(lck);
}
Task task;
if (!m_taskqueue.empty()) {
task = m_taskqueue.front();
m_taskqueue.pop();
}
return task;
}
#include <iostream>
#include<Windows.h>
#include"MyThreadPool.h"
//线程池 就是一个阻塞队列 和一堆线程
void func(int i) {
cout << "task finish" << "-----" << i << "线程id" << this_thread::get_id() << endl;
}
int main()
{
std::cout << "Hello World!\n";
MyThreadPool *pool = MyThreadPool::GetInstance();
pool->start(5);
int i = 0;
while (1)
{
i++;
auto task = bind(func, i);
pool->addTask(task);
}
pool->stop();
return 0;
}
测试截图