整理自《【C++】《C++ 并发编程实战 (第2版) 》笔记-Chapter9-高级线程管理》
1、线程池类,包括 AJoinThreads、AQueueThreadSafe、ATaskType、AStealTaskQueue、AMyThreadPool。其中,
AJoinThreads:RAII思想,析构时调用 join() 自动等待所有线程完成。
AQueueThreadSafe:基于 std::mutex 的线程安全的 queue,用于存放任务。
ATaskType:任务包装类。
AStealTaskQueue:基于 std::mutex 的线程安全的 deque,用于存放各个线程自己的任务,是一个可被其他线程窃取任务的队列。
AMyThreadPool:对外使用的主类,外面通过 submit() 函数提交任务给线程池并得到对应任务的 future。
#ifndef AMYTHREADPOOL_H
#define AMYTHREADPOOL_H
#include <functional>
#include <atomic>
#include <vector>
#include <thread>
#include <future>
#include <queue>
#include <memory>
#include <mutex>
#include <condition_variable>
// RAII思想,析构时调用 join() 自动等待所有线程完成。
class AJoinThreads
{
public:
explicit AJoinThreads(std::vector<std::thread> &threads)
: m_threads(threads)
{}
~AJoinThreads()
{
for(std::thread& t : m_threads)
{
if(t.joinable())
t.join();
}
}
private:
std::vector<std::thread> &m_threads;
};
// 基于 std::mutex 的线程安全的 queue,用于存放任务。
template<typename T>
class AQueueThreadSafe
{
public:
AQueueThreadSafe()
{}
AQueueThreadSafe(const AQueueThreadSafe<T> &other)
{
std::lock_guard<std::mutex> lk(other.m_mtx);
m_queueData = other.m_queueData;
}
void push(T newValue)
{
std::lock_guard<std::mutex> lk(m_mtx);
m_queueData.push(std::move(newValue));
m_cond.notify_one();
}
void wait_and_pop(T &value)
{
std::unique_lock<std::mutex> lk(m_mtx);
m_cond.wait(lk, [this]{ return false == m_queueData.empty(); });
value = m_queueData.front();
m_queueData.pop();
}
std::shared_ptr<T> wait_and_pop()
{
std::unique_lock<std::mutex> lk(m_mtx);
m_cond.wait(lk, [this]{ return false == m_queueData.empty(); });
std::shared_ptr<T> res(std::make_shared<T>(m_queueData.front()));
m_queueData.pop()