Thread convenience class
This commit is contained in:
parent
181b4eee2b
commit
52d21935f9
|
|
@ -1,4 +1,5 @@
|
|||
add_library(util
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Thread.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/StateMachine.cpp
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
@ -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
|
||||
)
|
||||
|
|
|
|||
Loading…
Reference in New Issue