Thread convenience class

This commit is contained in:
Ezra Taimuty-Loomis 2022-01-27 16:36:42 -05:00
parent 181b4eee2b
commit 52d21935f9
5 changed files with 156 additions and 0 deletions

View File

@ -1,4 +1,5 @@
add_library(util
${CMAKE_CURRENT_SOURCE_DIR}/Thread.cpp
${CMAKE_CURRENT_SOURCE_DIR}/StateMachine.cpp
)

95
src/util/Thread.cpp Normal file
View File

@ -0,0 +1,95 @@
#include "Thread.h"
#include "threadname.h"
#include "loguru.hpp"
namespace piscan {
ThreadBase::ThreadBase(std::string name) : name(name), _run(true) {
}
void ThreadBase::initialize() {
LOG_F(1, "Initializing");
}
void ThreadBase::deinitialize() {
LOG_F(1, "Deinitializing");
}
void ThreadBase::start() {
LOG_F(1, "Starting %s", name.c_str());
_run = true;
_thread = std::thread([this]() { (*this).run(); });
}
void ThreadBase::stop() {
LOG_F(1, "Stopping %s", name.c_str());
_run = false;
}
void ThreadBase::join() {
if (_thread.joinable()) {
_thread.join();
}
}
void ThreadBase::run() {
setThreadName(name.c_str());
initialize();
LOG_F(1, "Started");
while(isRunning()) {
main();
}
deinitialize();
LOG_F(1, "Stopped");
}
void WorkerThread::start() {
_stopping = false;
ThreadBase::start();
}
void WorkerThread::stop() {
ThreadBase::stop();
std::unique_lock<std::mutex> lock(_mtx);
_stopping = true;
_cv.notify_all();
}
void WorkerThread::run() {
setThreadName(name.c_str());
initialize();
LOG_F(1, "Started");
while (isRunning())
{
std::unique_lock<std::mutex> lock(_mtx);
while(!_workAvailable && !_stopping) {
_cv.wait(lock);
}
if(_workAvailable){
main();
}
else if(_stopping){
break;
}
}
deinitialize();
LOG_F(1, "Stopped");
}
bool ThreadBase::isRunning() {
return _run.load();
}
void WorkerThread::postWorkAvailable() {
std::unique_lock<std::mutex> lock(_mtx);
_workAvailable = true;
_cv.notify_all();
}
}

59
src/util/Thread.h Normal file
View File

@ -0,0 +1,59 @@
#pragma once
#include <thread>
#include <atomic>
#include <mutex>
#include <condition_variable>
namespace piscan {
class ThreadBase {
public:
virtual ~ThreadBase() {};
virtual void initialize();
virtual void deinitialize();
virtual void start();
virtual void stop();
virtual void join();
const std::string name;
protected:
ThreadBase(std::string name);
virtual void run();
virtual void main() = 0;
bool isRunning();
//Logger logger();
private:
std::atomic_bool _run;
std::thread _thread;
};
class WorkerThread : public ThreadBase {
public:
virtual void start();
virtual void stop();
protected:
WorkerThread(std::string name) : ThreadBase(name) {};
virtual ~WorkerThread(){};
virtual void run();
virtual void main() = 0;
void postWorkAvailable();
private:
std::mutex _mtx;
std::condition_variable _cv;
bool _workAvailable;
bool _stopping;
};
}

View File

@ -2,4 +2,5 @@ package_add_test(util_tests
${CMAKE_CURRENT_SOURCE_DIR}/IntervalTimer_test.cpp
${CMAKE_CURRENT_SOURCE_DIR}/StateMachine_test.cpp
${CMAKE_CURRENT_SOURCE_DIR}/synchronize_test.cpp
${CMAKE_CURRENT_SOURCE_DIR}/Thread_test.cpp
)

View File