线程池其实就是一堆处理任务的线程和 一个任务队列 ,处理线程不断地从这个任务队列中拿出任务进行处理。
不过需要注意的是 对于这个任务队列需要保证线程安全
一个简易的线程池需要
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;
}
测试截图