thread_pools
thread_pools copied to clipboard
dynamic_pool::make_worker Multithreaded safe use may crash
void dynamic_pool::make_worker()
{
auto thread = std::thread{[this]() {
while (true)
{
std::unique_lock<std::mutex> lock(m_queue_mu);
m_cv.wait(lock, [this]() { return m_shutdown || !m_task_queue.empty() || m_idle_num > m_max_idle_size; });
if (m_shutdown && m_task_queue.empty()) { return; } // Game over.
if (m_idle_num > m_max_idle_size && !m_shutdown)
{// Cut the idle threads.
destroy_worker(std::this_thread::get_id());
--m_idle_num;
return;
}
--m_idle_num;
auto task = std::move(m_task_queue.front());
m_task_queue.pop();
lock.unlock(); // LOCK IS OVER.
task();
++m_idle_num; // ATOMIC
}}};
++m_idle_num;
{
std::lock_guard<std::mutex> lk(m_map_mu); // After this lock is added, the problem is solved
m_workers[thread.get_id()] = std::move(thread);
}
}