//
// Created by zgp on 2021/5/15.
//
#include <vector>
#include <deque>
#include <thread>
#include <functional>
#include <mutex>
#include <assert.h>
#include <condition_variable>
class thread_pool{
public:
typedef std::function<void()> task_t;
thread_pool(int init_size = 3);
~thread_pool();
void stop();
void add_task(const task_t&); //thread safe; //http://www.voidcn.com/article/p-vgunmvfe-ca.html
private:
thread_pool(const thread_pool&);//禁止复制拷贝.
const thread_pool& operator=(const thread_pool&);
bool is_started() const { return m_is_started; }
void start();
void thread_loop();
task_t take();
typedef std::vector<std::thread*> threads_t;
typedef std::deque<task_t> tasks_t;
int m_init_threads_size;
threads_t m_threads;
tasks_t m_tasks;
std::mutex m_mutex;
std::condition_variable m_cond;
bool m_is_started;
};
thread_pool::thread_pool(int init_size)
:m_init_threads_size(init_size),
m_mutex(),
m_cond(),
m_is_started(false)
{
start();
}
thread_pool::~thread_pool()
{
if(m_is_started)
{
stop();
}
}
void thread_pool::start()
{
assert(m_threads.empty());
m_is_started = true;
m_threads.reserve(m_init_threads_size);
for (int i = 0; i < m_init_threads_size; ++i)
{
m_threads.push_back(new std::thread(std::bind(&thread_pool::thread_loop, this)));
}
}
void thread_pool::stop()
{
{
std::unique_lock<std::mutex> lock(m_mutex);
m_is_started = false;
m_cond.notify_all();
}
for (threads_t::iterator it = m_threads.begin(); it != m_threads.end() ; ++it)
{
(*it)->join();
delete *it;
}
m_threads.clear();
}
void thread_pool::thread_loop()
{
while(m_is_started)
{
task_t task = take();
if(task)
{
task();
}
}
}
void thread_pool::add_task(const task_t& task)
{
std::unique_lock<std::mutex> lock(m_mutex);
m_tasks.push_back(task);
m_cond.notify_one();
}
thread_pool::task_t thread_pool::take()
{
std::unique_lock<std::mutex> lock(m_mutex);
//always use a while-loop, due to spurious wakeup
while(m_tasks.empty() && m_is_started)
{
m_cond.wait(lock);
}
task_t task;
tasks_t::size_type size = m_tasks.size();
if(!m_tasks.empty() && m_is_started)
{
task = m_tasks.front();
m_tasks.pop_front();
assert(size - 1 == m_tasks.size());
/*if (TaskQueueSize_ > 0)
{
cond2.notify_one();
}*/
}
return task;
}
C++thread
最新推荐文章于 2022-12-24 11:29:19 发布