SingleThread.h:
#pragma once
#include <thread>
#include <queue>
#include <mutex>
#include <memory>
#include <condition_variable>
using TaskFun = std::function<void(void)>;
class CSingleThread {
public:
CSingleThread();
~CSingleThread();
bool start();
void stop();
bool post(const TaskFun& task_fun);
private:
void exec();
private:
bool exist_;
std::thread thread_;
std::queue<TaskFun> tasks_;
std::mutex mutex_;
std::condition_variable condition_;
std::queue<TaskFun> tasks_new_;
std::mutex mutex_new_;
};
SingleThread.cpp:
#include "SingleThread.h"
CSingleThread::CSingleThread()
: exist_(false)
{
}
CSingleThread::~CSingleThread() {}
bool CSingleThread::start() {
if (exist_) {
return false;
}
exist_ = true;
thread_ = std::thread(std::bind(&CSingleThread::exec, this));
return thread_.joinable();
}
void CSingleThread::stop() {
if (!exist_) {
return;
}
exist_ = false;
condition_.notify_all();
if (thread_.joinable()) {
thread_.join();
}
return;
}
bool CSingleThread::post(const TaskFun& task_fun) {
std::lock_guard<std::mutex> lock(mutex_new_);
tasks_new_.push(task_fun);
condition_.notify_one();
return true;
}
void CSingleThread::exec() {
while (exist_)
{
std::unique_lock<std::mutex> lock(mutex_);
if (tasks_.empty()) {
condition_.wait(lock);
}
if (!exist_) {
break;
}
{
std::lock_guard<std::mutex> lock(mutex_new_);
tasks_.swap(tasks_new_);
}
while (!tasks_.empty())
{
if (!exist_) {
break;
}
TaskFun task = tasks_.front();
tasks_.pop();
task();
}
}
return;
}
main:
#include <iostream>
#include "SingleThread.h"
int main() {
std::mutex m;
CSingleThread t;
t.start();
auto fun = [&]()
{
std::lock_guard<std::mutex> lock(m);
static int count = 0;
std::cout << "Count: " << ++count << "thread-id: " << std::this_thread::get_id() << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(1));
};
for (int i = 0; i < 20; ++i)
{
t.post(fun);
//std::this_thread::sleep_for(std::chrono::microseconds(500));
}
getchar();
t.post(fun);
getchar();
t.stop();
return 0;
}