#include <iostream>
#include <thread>
#include <chrono>
#include <vector>
#include <list>
#include <algorithm>
#include <mutex>
#include <atomic>
using namespace std;
class TaskThreadPool
{
public:
typedef std::function<void()> Task;
public:
TaskThreadPool(int threadnum) : m_bStop(false) {
for (int i = 0; i < threadnum; i++)
m_TaskThreadPool.emplace_back(thread(TaskRunThread, this));
}
~TaskThreadPool() {
Stop();
}
void InsertTask(Task&& task) {
lock_guard<mutex> autolock(m_TaskListMutex);
m_TaskList.emplace_back(task);
m_TaskListCond.notify_one();
}
bool IsTaskListEmpty() {
lock_guard<mutex> autolock(m_TaskListMutex);
return m_TaskList.empty();
}
void Stop() {
m_bStop = true;
m_TaskListCond.notify_all();
Join();
m_TaskList.clear();
}
void Join() {
for (auto &th : m_TaskThreadPool) {
if (th.joinable())
th.join();
}
}
private:
static void TaskRunThread(TaskThreadPool *pThis) {
while (!pThis->m_bStop) {
Task task = NULL;
{
unique_lock<mutex> autolock(pThis->m_TaskListMutex);
if (pThis->m_TaskList.empty())
pThis->m_TaskListCond.wait(autolock);
if (!pThis->m_TaskList.empty())
{
task = std::move(pThis->m_TaskList.front());
pThis->m_TaskList.pop_front();
}
}
if (task) {
task();
}
}
}
private:
vector<thread> m_TaskThreadPool;
list<Task> m_TaskList;
mutex m_TaskListMutex;
condition_variable m_TaskListCond;
atomic<bool> m_bStop;
};
void TaskFunc(int id) {
static mutex loglock;
loglock.lock();
cout << "Thread(" << this_thread::get_id() << ") run task(" << id << ")\n";
loglock.unlock();
this_thread::sleep_for(chrono::milliseconds(100));
}
int main()
{
TaskThreadPool pool(5);
for (int i = 0; i < 100; i++)
pool.InsertTask(std::bind(TaskFunc, i));
while (!pool.IsTaskListEmpty())
this_thread::sleep_for(chrono::milliseconds(1000));
return 0;
}