C++ 线程类封装
在实现一个通知的时候上网找资料,发现这位大佬的实现跟我极其相似,草哈哈哈哈
当然线程模块还有很多实现方式
- 比如在Task中定义线程入口函数,外部去注册函数,然后运行。
- 也可以是不让Task成为抽象类,可以作为外面功能模块的成员,接收外面功能模块的函数注册,然后运行,都可以。
对了其中std::optional 是cpp17的 你可以替换成bool类型
不多说了,直接上代码
task.hpp
#pragma once
#include <atomic>
#include <condition_variable>
#include <functional>
#include <memory>
#include <mutex>
#include <thread>
namespace utility {
class Task {
enum class State : char {
kEnd,
kPaused,
kRunning,
};
public:
Task(bool autoStop);
virtual ~Task();
bool start();
bool stop();
bool pause();
bool resume();
protected:
virtual bool threadProcess() = 0;
private:
void run();
private:
State state_;
std::atomic_bool autoStop_;
std::unique_ptr<std::thread> task_;
std::mutex lock_;
std::condition_variable cv_;
};
} // namespace utility
task.cpp
#include "utils_thread.hpp"
#include <iostream>
#include "iso646.h"
namespace utility {
Task::Task(bool autoStop) : state_{State::kEnd}, autoStop_{autoStop}, task_{} {}
Task::~Task() { task_.reset(); }
bool Task::start() {
if (nullptr != this->task_.get() and this->state_ == State::kRunning) {
return true;
}
state_ = State::kRunning;
task_.reset(new std::thread(&Task::run, this));
return true;
}
bool Task::stop() {
if (nullptr == this->task_.get() and State::kEnd == this->state_) {
return true;
}
if (nullptr != this->task_.get() and State::kPaused == this->state_) {
std::cout << "make run\n";
resume(); // 由挂起变为运行
}
// 通过上面流程,以下为运行状态
this->state_ = State::kEnd;
if (!this->task_->joinable()) {
std::cout << "joinable : false\n";
return false;
}
this->cv_.notify_one();
this->task_->join();
this->task_.reset();
return true;
}
bool Task::pause() {
if (nullptr != this->task_.get() and State::kRunning == this->state_) {
this->state_ = State::kPaused;
return true;
}
return false;
}
bool Task::resume() {
if (nullptr != this->task_.get() and State::kPaused == this->state_) {
this->state_ = State::kRunning;
this->cv_.notify_one();
return true;
}
return false;
}
auto Task::run() -> void {
std::cout << "run pid:" << std::this_thread::get_id() << std::endl;
do {
if (this->autoStop_.load() == true) {
if (!threadProcess()) {
pause();
}
} else {
threadProcess();
}
while (State::kPaused == this->state_) {
std::unique_lock<std::mutex> locker(this->lock_);
std::cout << "sleep" << std::endl;
this->cv_.wait(locker);
std::cout << "wake up, "
<< " now state:" << int(this->state_) << std::endl;
}
} while (State::kEnd != this->state_);
std::cout << "exit pid:" << std::this_thread::get_id() << std::endl;
}
} // namespace utility
woker.hpp
Woker 继承 utility::Task,实现threadProcess()
接口
#pragma once
#include "utils_thread.hpp"
class Worker : public utility::Task {
public:
Worker() : utility::Task(true) { }
~Worker() override {
stop();
}
bool threadProcess() override {
std::string str("nihao!");
std::cout << str << "\t";
using namespace std::literals;
std::this_thread::sleep_for(10ms);
return true;
}
};
main.cpp
#include "woker.hpp"
using namespace std::literals;
int main() {
Worker woker{};
woker.start();
std::this_thread::sleep_for(3s);
woker.pause();
std::this_thread::sleep_for(3s);
woker.resume();
std::this_thread::sleep_for(3s);
woker.stop();
return 0;
}
后续会在work::Task
类上做扩展,实现zmq
网络收发模块的集成,以及实现一个v4l2
+ffmpeg
的一套流程。
to be continue...