主要是用于记录自己的练习,不保证正确,请勿参考
#ifndef THREADPOOL_H_INCLUDED
#define THREADPOOL_H_INCLUDED
#include<thread>
#include<future>
#include<iostream>
#include<vector>
#include<memory>
#include<functional>
#include<atomic>
#include "../../../../../spdlog/spdlog.h"
#include "../../../../../spdlog/sinks/basic_file_sink.h"
#include "../../../../../spdlog/sinks/rotating_file_sink.h"
#include "../../../../../spdlog/sinks/daily_file_sink.h"
#include "../../../../../spdlog/details/os.h"
#include "../../../../../spdlog/details/os-inl.h"
#include "../data_structures/ThreadSafeQueue.h"
#include "../data_structures/ThreadSafeQueue1.h"
using namespace com::example::testone::thread::data_structures;
namespace com{
namespace example{
namespace testone{
namespace thread{
namespace thread_pool{
class ThreadPool{
public:
ThreadPool()
{
spdlog::debug("ThreadPool construct start");
this->mIsStop = false;
this->mThreadSize = std::thread::hardware_concurrency();//使用硬件支持的并发数
//this->mThreadSize = 1;
//std::cout << "this->mThreadSize = " << this->mThreadSize << std::endl;
for(int i = 0; i < this->mThreadSize; i++)
{
this->mThreads.push_back(std::thread([&]()
{
while(! this->mIsStop)
{
std::shared_ptr<std::function<void()>> p = this->mQueue.try_pop();
if(p)
{
//std::cout << "取出任务..." << std::endl;
//spdlog::debug("ThreadPool try_pop not empty");
(*p)();
}
else
{
std::this_thread::yield();//暂停当前正在执行的线程对象,并执行其他线程
}
}
}));
}
spdlog::debug("ThreadPool construct end");
}
~ThreadPool(){
spdlog::debug("...........start Deconstruction , wait threads stop...............");
stop();
}
public:
template<typename Func, typename... Args>
std::future<typename std::result_of<Func(Args...)>::type> commitTask(Func&& f, Args&&... args)
{
//spdlog::debug("ThreadPool commitTask start");
using RetType = typename std::result_of<Func(Args...)>::type;
std::shared_ptr<std::packaged_task<RetType()>> p = std::make_shared<std::packaged_task<RetType()>>(
std::bind(std::forward<Func>(f), std::forward<Args>(args)...)
);
std::future<RetType> resFuture = p->get_future();
//将packaged_task转换成符合要求的function,放入队列中
this->mQueue.push([p]()
{
(*p)();
});
//spdlog::debug("ThreadPool commitTask success");
return resFuture;
}
public:
void stop(){
this->mIsStop = true;
for(int i = 0; i < this->mThreadSize; i++){
this->mThreads.at(i).join();
}
}
private:
ThreadSafeQueue1<std::function<void()>> mQueue;
std::vector<std::thread> mThreads;
std::atomic<bool> mIsStop;
unsigned int mThreadSize;
};
}
}
}
}
}
#endif // THREADPOOL_H_INCLUDED
#ifndef THREADSAFEQUEUE1_H_INCLUDED
#define THREADSAFEQUEUE1_H_INCLUDED
#include<queue>
#include<mutex>
#include<memory>
#include "../../../../../spdlog/spdlog.h"
#include "../../../../../spdlog/sinks/basic_file_sink.h"
#include "../../../../../spdlog/sinks/rotating_file_sink.h"
#include "../../../../../spdlog/sinks/daily_file_sink.h"
#include "../../../../../spdlog/details/os.h"
#include "../../../../../spdlog/details/os-inl.h"
namespace com{
namespace example{
namespace testone{
namespace thread{
namespace data_structures{
template<typename T>
class ThreadSafeQueue1{
public:
void push(T t){
//spdlog::debug("ThreadSafeQueue1 start push");
std::lock_guard<std::mutex> lk(this->mMtx);
this->mQueue.push(std::make_shared<T>(std::move(t)));
//spdlog::debug("ThreadSafeQueue1 push success");
}
/**
* 用size = 0判断为空,不要用this->mQueue.front() = null来判断
*/
std::shared_ptr<T> try_pop(){
std::lock_guard<std::mutex> lk(this->mMtx);
//spdlog::debug("ThreadSafeQueue1 size = {}", this->mQueue.size());
if(this->mQueue.size() == 0){
//spdlog::debug("ThreadSafeQueue1 try_pop empty");
return std::shared_ptr<T>();
}
std::shared_ptr<T> res = this->mQueue.front();
this->mQueue.pop();
//spdlog::debug("ThreadSafeQueue1 try_pop not empty");
return res;
}
private:
std::queue<std::shared_ptr<T>> mQueue;
std::mutex mMtx;
};
}
}
}
}
}
#endif // THREADSAFEQUEUE1_H_INCLUDED