一、依据网上相关文章,实现C++线程池的具体操作
1.创建线程池,使用到模板、任务队列、STL、c++11新特性
#C++线程池源码
#ifndef THREAD_POOL_H
#define THREAD_POOL_H
#endif // THREAD_POOL_H
#include <iostream>
#include <vector>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <queue>
#include <functional>
#include <future>
//线程池类
class ThreadPool{
public:
using Task = std::function<void()>;
private:
std::vector<std::thread> workes; //工作线程
std::queue<Task> tasks; //任务队列
std::condition_variable cv;
std::mutex mtx; //锁
bool stopped;
public:
ThreadPool(size_t threads) : stopped(false) {
for (size_t i = 0; i < threads; ++i) {
workes.emplace_back([this] {
while (true) {
std::function<void()> task;
{
std::unique_lock<std::mutex> lock(this->mtx);
this->cv.wait(lock, [this] { return this->stopped || !this->tasks.empty(); });
if (this->stopped && this->tasks.empty())
return;
task = std::move(this->tasks.front());
this->tasks.pop();
}
task();
}
});
}
}
//传递函数和变量的线程池任务函数
template<class F, class... Args>
auto enqueue(F&& f, Args&&... args) -> std::future<typename std::result_of<F(Args...)>::type>{
using return_type = typename std::result_of<F(Args...)>::type;
auto task = std::make_shared<std::packaged_task<return_type()>>(std::bind(std::forward<F>(f), std::forward<Args>(args)...));
std::future<return_type> res = task->get_future();
{
std::unique_lock<std::mutex> lock(mtx);
if(stopped){
throw std::runtime_error("enqueue on stopped ThreadPool");
}
tasks.emplace([task](){(*task)(); });
}
cv.notify_one();
return res;
}
~ThreadPool(){
{
std::unique_lock<std::mutex> lock(mtx);
stopped = true;
}
cv.notify_all();
for(std::thread &worker: workes){
worker.join();
}
}
};
2、使用方法
一个是线程池直接使用函数,一个是对象的方式传入线程池(定义对象)
#include <iostream>
#include "thread_pool.h"
using namespace std;
int Func(int number1, int number2, char type)
{
int sum = 0;
switch (type) {
case '+':
sum = number1 + number2;
std::cout << "计算加的结果:" << sum << std::endl;
break;
case '-':
sum = number1 - number2;
std::cout << "计算减的结果:" << sum << std::endl;
break;
case '/':
sum = number1 / number2;
std::cout << "计算除的结果:" << sum << std::endl;
break;
case '*':
sum = number1 * number2;
std::cout << "计算乘的结果:" << sum << std::endl;
break;
default:
break;
}
return sum;
}
class A{
public:
void printf_str(std::string str_1)
{
std::cout << "输出参数为:" << str_1 << std::endl;
}
};
void taskFunctionClass(std::shared_ptr<A> obj, std::string str_1)
{
obj->printf_str(str_1);
}
int main()
{
cout << "Hello World!" << endl;
ThreadPool pool(4);
std::function<void(int,int,char)> func_bind = std::bind(Func, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
//提交任务到线程池
int a = 10;
int b = 30;
char t = '/';
func_bind(10, 30, '+');
for(int i = 0; i < 10; i++)
{
b += i;
pool.enqueue(func_bind, i, i+10, '+');
//std::cout << result_data.get() << std::endl;
}
auto obj = std::make_shared<A>();
for(int i = 0; i < 4; i++)
{
std::string str = "测试函数标识位:" + std::to_string(i) + "标识";
auto func = [obj, str](){taskFunctionClass(obj, str);};
pool.enqueue(func);
}
}