1,首先,创建一个继承的子类的任务对象
MyTask task1
2,然后将task1添加到任务队列当中
AddTask(task1);
list<XTask*> m_task.push_back(task1);
然后发射条件变量进行通知,
cv.notify_one();
1.1 初始化线程池
Init();
1.2 开启线程池,
1.2.1 先new一个新的thread,new的时候就已经调用Run()了
1.2.3 Run()中先检查任务队列是否为空,为空就阻塞等待条件变量
cv.wait();
不为空的话就可调用GetTask获取队列中的任务,
获取之后,直接调用Run,队列模板类型是XTask的父类的类型,但是我们刚才存的
却是子类的对象的地址,所以这就是父类指针指向子类对象,就可以用多态来调用
子类的Run()函数啦。
threadPool.h文件
#pragma once
#include<iostream>
#include<mutex>
#include<vector>
#include<list>
class XTask
{
public:
virtual int Run() = 0;
};
//线程池
class XThreadPool
{
public:
//初始化线程池,线程数量
void Init(int num);
//启动所有线程,启动前必须先调用Init(int num)
void Start();
//添加任务
void AddTask(XTask* task);
//获取任务
XTask* GetTask();
private:
//线程池线程的入口函数
void Run();
int thread_num = 0; //线程数量
std::mutex m_mux;
std::vector<std::thread*> m_threads;
std::list<XTask*> m_tasks;
std::condition_variable cv; //条件变量
};
threadPool.cpp文件
#include"threadPool.h"
using namespace std;
//初始化线程
void XThreadPool::Init(int num)
{
unique_lock<mutex> lock(m_mux);
this->thread_num = num;
cout << "Thread pool Init " << num << endl;
}
//线程池线程的入口函数
void XThreadPool::Run()
{
cout << "begin XThreadPool Run "<<endl;
while (true)
{
auto task = GetTask();
if (!task)
{
continue;
}
try {
task->Run();
}
catch (...)
{
}
}
//cout << "end XThreadPool Run " << this_thread::get_id() << " " << endl;
}
//启动所有线程,启动前必须先调用Init(int num)
void XThreadPool::Start()
{
unique_lock<mutex> lock(m_mux);
if (thread_num <= 0)
{
cout << "Please Init XThreadPool" << endl;
return;
}
//启动线程
for (int i = 0; i < thread_num; i++)
{
auto th = new thread(&XThreadPool::Run,this);
m_threads.push_back(th);
}
}
//添加任务
void XThreadPool::AddTask(XTask* task)
{
unique_lock<mutex> lock(m_mux);
m_tasks.push_back(task);
lock.unlock();
cv.notify_one(); //通知
}
XTask* XThreadPool::GetTask()
{
unique_lock<mutex> lock(m_mux);
if (m_tasks.empty())
{
cv.wait(lock); //如果为空,就在这里一直阻塞,等待通知
}
if (m_tasks.empty())
{
return nullptr;
}
auto task = m_tasks.front();
m_tasks.pop_front();
return task;
}
main.cpp文件
#include"threadPool.h"
class MyTask :public XTask
{
public:
int Run()
{
std::cout << "Mytask" << name << std::endl;
return 0;
}
std::string name = " ";
};
int main()
{
XThreadPool pool;
pool.Init(10);
pool.Start();
MyTask task1;
task1.name = "test name01";
pool.AddTask(&task1);
getchar();
return 0;
}