cppthreadconsole.h
#include<iostream>
#include<thread>
#include<memory>
#include <queue>
#include <condition_variable>
#include <functional>
class ThreadPool;
class ThreadPool{
public:
enum PoolStatus{ Run, Stop, Wait };
template<class F, class ...Args>
bool enqueue(F &&f, Args && ...args);
void setPoolStatus(PoolStatus s);
static ThreadPool& getInstance();
//static void deleteInstance();
private:
//static ThreadPool* myThreadpool;
std::vector<std::thread> poolthreads_; //线程数组
std::queue<std::function<void()>> tasks_; //任务队列
std::condition_variable condition_; // 可用线程的条件变量
PoolStatus status_;
std::mutex poolmutex_;//写其他成员变量的互斥锁
// 获取单实例
private:
ThreadPool(int initThreanum = 10);
~ThreadPool();
// 禁止外部复制构造
ThreadPool(const ThreadPool &signal) = delete;
// 禁止外部赋值操作
ThreadPool &operator=(const ThreadPool &signal) = delete;
};
void test(){
for (int i = 0; i < 5; i++)
{
ThreadPool::getInstance().enqueue([i]{
std::cout << "task:" << i << " is running " << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(1));
std::cout << "task:" << i << " has finish " << std::endl;
});
}
std::cout << "Main:set Stopping" << std::endl;
ThreadPool::getInstance().setPoolStatus(ThreadPool::Wait);
std::this_thread::sleep_for(std::chrono::seconds(2));
std::cout << "Main:set Running" << std::endl;
ThreadPool::getInstance().setPoolStatus(ThreadPool::Run);
std::this_thread::sleep_for(std::chrono::seconds(1));
}
int main(){
test();
std::this_thread::sleep_for(std::chrono::seconds(3));
system("pause");
return 0;
}
cppthreadconsole.cpp
#include<iostream>
#include<thread>
#include<memory>
#include <queue>
#include <condition_variable>
#include <functional>
#include "cppthreadconsole.h"
template<class F,class ...Args>
bool ThreadPool::enqueue(F &&f, Args && ...args){//函数模板里面,右值引用就是通用引用,传入是左值就是左值,右值就是右值
//函数绑定,函数适配器。 std::forward 完美转发,原来是啥引用就是啥引用。
std::function<void()> task = std::bind(std::forward<F>(f), std::forward<Args>(args)...);
if (PoolStatus::Wait == status_ || PoolStatus::Run == status_)
{
{
std::unique_lock<std::mutex> lock(poolmutex_);
tasks_.emplace(std::move(task));
}
condition_.notify_one();
return true;
}
return false;
}
void ThreadPool::setPoolStatus(ThreadPool::PoolStatus s){
if (status_ != ThreadPool::Stop)
{
status_ = s;
}
}
ThreadPool& ThreadPool::getInstance(){
static ThreadPool myThreadpool(4);
return myThreadpool;
}
ThreadPool::ThreadPool(int initThreanum ) :status_(PoolStatus::Run){
//创建initThreanum 个线程,并开始消耗对应条件变量任务队列中的任务,任务队列空则等待
for (int i = 0; i < initThreanum; i++)
{
poolthreads_.emplace_back([this]{
while (1)
{
//死循环读取任务,没任务则阻塞
std::unique_lock<std::mutex> lock(poolmutex_);
condition_.wait(lock, [this]{
return !tasks_.empty()
|| status_ == PoolStatus::Stop;
});
//std::function<void()> task = tasks_.front();
if (status_ == PoolStatus::Stop && tasks_.empty()){
return;
}
while (status_ == PoolStatus::Wait){
std::this_thread::sleep_for(std::chrono::seconds(1));
//无需释放锁,其他线程跟着阻塞
}
std::function<void()> task(std::move(tasks_.front()));
tasks_.pop();
//解锁执行函数task
lock.unlock();
task();
}
});
}
}
ThreadPool::~ThreadPool(){
std::cout << "析构" << std::endl;
{
//析构函数等待线程执行完毕或者全部终止
//std::unique_lock<std::mutex> lock(poolmutex_);
status_ = PoolStatus::Stop;
}
condition_.notify_all();
for (auto &thread : poolthreads_)
{
if (thread.joinable()){
thread.join();
}
}
}