#include <mutex>
#include <condition_variable>
#include <functional>
#include <queue>
#include <thread>
class ThreadPool
{
struct TPData {
std::mutex mtx_;
std::condition_variable cond_;
bool is_shutdown_ = false;
std::queue<std::function<void()>> tasks_;
};
public:
ThreadPool(int num_threads)
{
m_num_threads = num_threads;
m_data = std::make_shared<TPData>();
for (int i =0;i< m_num_threads;i++)
{
m_threads.emplace_back(
[this]
{
for (;;)
{
// task是一个函数类型,从任务队列接收任务
std::function<void()> task;
{
//给互斥量加锁,锁对象生命周期结束后自动解锁
std::unique_lock<std::mutex> lock(this->m_data->mtx_);
//(1)当匿名函数返回false时才阻塞线程,阻塞时自动释放锁。
//(2)当匿名函数返回true且受到通知时解阻塞,然后加锁。
this->m_data->cond_.wait(lock, [this] { return this->m_data->is_shutdown_ || !this->m_data->tasks_.empty(); });
if (this->m_data->is_shutdown_ && this->m_data->tasks_.empty())
break;
//从任务队列取出一个任务
task = std::move(this->m_data->tasks_.front());
this->m_data->tasks_.pop();
} // 自动解锁
task(); // 执行这个任务
}
}
);
}
}
~ThreadPool()
{
if (m_num_threads>0)
{
m_data->is_shutdown_ = true;
m_data->cond_.notify_all();
for (int i =0;i< m_num_threads;i++)
{
m_threads[i].join();
}
}
}
template <class F>
void execute(F&& task) {
{
std::lock_guard<std::mutex> lk(m_data->mtx_);
m_data->tasks_.emplace(std::forward<F>(task));
}
m_data->cond_.notify_one();
}
private:
private:
int m_num_threads;
std::vector<std::thread> m_threads;
std::shared_ptr<TPData> m_data;
};
int global_value = 0;
void foof1()
{
std::this_thread::sleep_for(std::chrono::seconds(5));
std::cout << " global_value" << std::endl;
}
void foof2()
{
std::this_thread::sleep_for(std::chrono::seconds(5));
std::cout << " global_value2" << std::endl;
}
void foof3()
{
std::this_thread::sleep_for(std::chrono::seconds(5));
std::cout << " global_value3" << std::endl;
}
void foof4()
{
std::this_thread::sleep_for(std::chrono::seconds(5));
std::cout << " global_value3" << std::endl;
}
void mainThreadPool()
{
ThreadPool tp(5);
tp.execute(foof1);
tp.execute(foof1);
tp.execute(foof1);
tp.execute(foof1);
tp.execute(foof1);
tp.execute(foof1);
tp.execute(foof1);
tp.execute(foof1);
tp.execute(foof2);
tp.execute(foof3);
tp.execute(foof4);
}