SIMOrthoProgram-Orth_GF3-Strip/PSTM_simulation_windows2021.../PSTM_simulation_windows/threadpool.cpp

183 lines
4.7 KiB
C++
Raw Normal View History

#include "threadpool.hpp"
#include <sstream>
#include <string>
//#include <unistd.h>
#include <windows.h>
static const int MAX_THREADS = 10000; //最大线程数目
/**
* @brief ThreadPool
* @param number[in]线 *线
* @param
* emptyQuit[in]线退falsetruestartwaite
*/
ThreadPool::ThreadPool(int number, bool emptyQuit)
: m_StopFlag(false), m_EmptyQuit(emptyQuit), m_JoinFlag(false), m_QuitNum(0), m_EmptyQuitWaite(false) {
std::cout << "线程池中线程数:" << number << std::endl;
if (number <= 0 || number > MAX_THREADS) throw std::exception();
m_ThreadNum = number;
}
ThreadPool::~ThreadPool() {
// std::cout << "~ThreadPool()" << std::endl;
stop();
}
/**
* @brief stop
*/
void ThreadPool::stop() {
//保证多线程情况下只调用一次stopThreadGroup
std::call_once(m_CallStopSlag, [this] { stopThreadGroup(); });
}
/**
* @brief stopThreadGroup 线
*/
void ThreadPool::stopThreadGroup() {
m_StopFlag = true;
Sleep(500);
m_Condition.notify_all();
waiteFinish(); //等待线程退出
std::thread* thread = NULL;
for (int i = 0; i < m_WorkThreads.size(); i++)
{
thread = m_WorkThreads[i];
if (thread != NULL)
{
thread->join();
delete thread;
thread = NULL;
}
m_WorkThreads[i] = NULL;
}
m_WorkThreads.clear();
}
/**
* @brief startThread 线
*/
void ThreadPool::startThread() {
for (int i = 0; i < m_ThreadNum; i++) {
std::thread* thread = new std::thread(ThreadPool::worker, this);
m_WorkThreads.push_back(thread);
}
}
/**
* @brief waiteThreadFinish 线
*/
void ThreadPool::waiteThreadFinish() {
if (m_JoinFlag) return;
if (m_EmptyQuit)
{
m_EmptyQuitWaite = true;
do
{
if (m_ThreadNum == m_QuitNum)
break;
Sleep(400);
} while (true);
m_StopFlag = true;
m_Condition.notify_all();
}
/* for (int i = 0; i < work_threads.size(); i++) {
if (work_threads[i]) { work_threads[i]->join(); }
}*/
m_JoinFlag = true;
}
/**
* @brief start
*/
void ThreadPool::start() {
std::call_once(m_CallStartSlag, [this] { startThread(); });
}
/**
* @brief waiteFinish ,退
*/
void ThreadPool::waiteFinish() {
std::call_once(m_CallWaiteFinisFlag, [this] { waiteThreadFinish(); });
}
/**
* @brief
*/
int ThreadPool::taskNum()
{
return m_TasksQueue.size();
}
/**
* @brief append task_queue<T *>
* @param task
* @return
*/
bool ThreadPool::append(Task task) {
/*操作工作队列时一定要加锁,因为他被所有线程共享*/
m_DataMutex.lock();
m_TasksQueue.push(task);
m_DataMutex.unlock();
m_Condition.notify_one(); //线程池添加进去了任务,自然要通知等待的线程
return true;
}
/**
* @brief worker 线
* @param arg
* @return
*/
void* ThreadPool::worker(void* arg) {
ThreadPool* pool = (ThreadPool*)arg;
pool->run();
return pool;
}
/**
* @brief notEmpty
* @return
*/
bool ThreadPool::notEmpty() {
bool empty = m_TasksQueue.empty();
if (empty) {
// std::ostringstream oss;
// oss << std::this_thread::get_id();
// printf("queue empty thread id %s waite...!\n", oss.str().c_str());
}
return !empty;
}
/**
* @brief run 线,
*/
void ThreadPool::run() {
bool flag = false;
int remainder = 0;
while (!m_StopFlag) {
flag = false;
{
std::unique_lock<std::mutex> lk(this->m_QueueMutex);
/* unique_lock() 出作用域会自动解锁 */
m_Condition.wait(lk, [this] { return m_StopFlag || notEmpty(); });
}
if (m_StopFlag) break;
Task task;
m_DataMutex.lock();
//如果任务队列不为空,就停下来等待唤醒
if (!this->m_TasksQueue.empty()) {
task = m_TasksQueue.front();
m_TasksQueue.pop();
remainder = m_TasksQueue.size();
flag = true;
}
m_DataMutex.unlock();
if (flag) task();
//如果队列为空并且完成退出,已经开始等待退出就退出
if (m_TasksQueue.empty() && m_EmptyQuit && m_EmptyQuitWaite)
{
break;
}
}
m_QuitNum += 1;
std::ostringstream oss;
oss << std::this_thread::get_id();
printf("thread %s end\n", oss.str().c_str());
}