I want my class to spawn two threads, that will run in a loop and interact with the owner class. This was easy, when I had my class with single thread at first: one atomic flag, one mutex etc. But as the requirement for second thread rose, I am thinking of some more elegant solution, that will encapsulate the thread and its utilities. Such as: a ThreadWrapper class, that could be instantiated in the owner class.
So far, I came up with the following, however I am not certain if this is the right way to go:
class ThreadWrapper
{
public:
ThreadWrapper()
: m_threadShouldRun(false)
, m_threadRunning(false)
{
}
ThreadWrapper(std::function<void()> fn)
: m_threadShouldRun(true)
, m_threadRunning(false)
, m_threadFunction(fn)
{
m_threadPointer = std::make_shared<std::thread>(std::thread([&] { this->treadLoop(); }));
}
virtual ~ThreadWrapper()
{
if (m_threadRunning)
m_threadShouldRun = false;
m_threadPointer->join();
m_threadPointer = nullptr;
}
private:
void threadLoop()
{
m_threadRunning = true;
while(m_threadShouldRun)
{
std::this_thread::sleep_for(std::chrono::milliseconds(100));
m_threadFunction();
}
m_threadRunning = false;
}
std::function<void()> m_threadFunction = []{};
std::shared_ptr<std::thread> m_threadPointer;
std::atomic<bool> m_threadShouldRun;
std::atomic<bool> m_threadRunning;
};
Usage:
class Foo
{
Foo()
: t1(this->internalLoop1)
, t2(this->internalLoop2)
{
}
ThreadWrapper t1;
ThreadWrapper t2;
std::mutex mtx;
internalLoop1()
{
// looped task
{
std::scoped_lock lock(mutex);
}
}
internalLoop2()
{
// looped task
{
std::scoped_lock lock(mutex);
}
}
}
This is somewhat similar to a Wrapper that I found here. The shortcoming is that the sleep period needs to be passed to the ThreadWrapper object.
Is this a correct approach? Or maybe it should be done with a basis class and just inherited virtual method instead? As shown on the pic below. 
Source: https://www.codeproject.com/Articles/18383/A-thread-wrapper-class
Ideally I would like to use a template here, however the only "different" part between both ThreadWrapper is a single method, which rather suggests me inheritance/function pointers. Or am I wrong here?
Aucun commentaire:
Enregistrer un commentaire