Start a daemon thread that's a private method of the class? - c++

I'm new to C++11 threading and I'm trying to do something as follows:
class Something {
public:
void start() {
this->task_ = std::thread(&Something::someTask, this);
this->isRunning_ = true;
this->task_.detach(); // I read detach will stop it from hanging
}
void stop() {
this->isRunning = false;
}
~Something() {
this->stop();
}
private:
std::atomic<bool> isRunning_;
std::thread task_;
void someTask()
{
while(this->isRunning_) {
// do something forever
}
}
};
Something whatever;
whatever.start();
However, the thread keeps getting blocked. Like nothing after whatever.start() executes. It just hangs while the loop runs.

The usual pattern to do this is
class Something {
public:
void start() {
this->task_ = std::thread(&Something::someTask, this);
// this->task_.detach(); <<<<<< Don't do that.
}
void stop() {
this->isRunning_ = false;
task_.join(); // <<< Instead of detaching the thread, join() it.
}
~Something() {
this->stop();
}
private:
std::atomic<bool> isRunning_;
std::thread task_;
void someTask()
{
this->isRunning_ = true;
while(this->isRunning_) {
// do something forever
}
}
};
Detaching a std::thread usually isn't a good idea, unless there's some kind of synchronization set up, that allows to wait for the thread execution to end before the process ends as a whole.
Demonizing a process usually is realized with a fork() to create a background child process, and leave the parent process to return control to the caller.

I recently wrote a generic class that does just this
#include<functional>
#include<thread>
//do action asynchronously until condition is false
class do_async_until{
public:
do_async_until(std::function<void(void)> action,
std::function<bool(void)> condition);
~do_async_until();
void start();
void stop();
private:
void _do();
std::thread _worker;
std::function<void(void)> _action;
std::function<bool(void)> _condition;
};
//implementation
do_async_until::do_async_until(std::function<void(void)> action,
std::function<bool(void)> condition):_action(action),
_condition(condition){
}
do_async_until::~do_async_until(){
stop();
}
void do_async_until::start(){
_worker = std::thread(std::bind(&do_async_until::_do,this));
}
void do_async_until::stop(){
if(_worker.joinable()){
_worker.join();
}
}
void do_async_until::_do(){
while (_condition())
{
_action();
}
}
this will run any function with the signiture void(void) until the condition function bool(void) returns true
example usage:
int main(int agrc,char** argv){
bool running = true;
auto do_this = [](){
std::cout<<"hello world"<<std::endl;
};
auto condition = [&](){
return running;
};
do_async_until async(do_this,condition);
async.start();
std::this_thread::sleep_for(std::chrono::seconds(1));
running=false;
return 0;
}
The example should print "hello world" a bunch of times for one seconds then exit.
EDIT: to make this work with a member function you simply need to have an instance of do_async_until inside you class and pass the member function to the constructor of do_async_until using std::bind(&foo::func,this)

Related

Class variable has default value in each function call?

In MyClass there are two functions. FuncA sends a command to be executed while FuncB checks the progress in executing the command sent by FunA. As FuncB waits in a while loop until it makes sure the command was successfully executed, I call FuncB in a separate thread. The thread in which FunA is running should not wait in a while loop.
In main.cpp, there are two functions which run in two different threads. execute makes decisions and call FunA to send commands while check calls FuncB to check the made decisions has been executed.
As I don't want execute to send the same decision more than once, I first make sure that FuncA is not running and that FuncB has reset funcInUse to false.
myclass.h
class MyClass
{
public:
MyClass();
void FuncA(float x, floaty, floatz);
bool FuncB(void);
bool IsFuncInUse(void);
void QuitFuncA(void);
private:
bool funcInUse;
bool _x;
std::mutex mtx;
}
myclass.cpp
MyClass::MyClass()
{
funcInUse = false;
}
void MyClass::FuncA(float x, float y, float z)
{
if(funcInUse == true)
{
printf("FuncA already in use\n");
return;
}
// Gaining the lock, so that no two threads call the function at the same time
mtx.lock();
funcInUse = true;
mtx.unlock();
printf("INSIDE FuncA()::: %d\n", funcInUse?1:0);
printf("THIS FuncA() adr=%p \n", this);
// DO STUFF
}
bool MyClass::FuncB(void)
{
if(funcInUse == true)
{
printf("THIS ISPOSREACHED() adr=%p \n", this);
// DO STUFF
// Giving the lock back before returning
mtx.lock();
funcInUse = false;
mtx.unlock();
printf("Function is no more in use\n");
}
return true;
}
bool MyClass:IsFuncInUse(void)
{
return isFuncInUse;
}
void MyClass:QuitFuncA(void)
{
mtx.lock();
funcInUse = false;
mtx.unlock();
}
main.cpp
MyClass myClass;
void timerStart(std::function<void(void)> func, unsigned int interval)
{
std::thread([func, interval]()
{
while (true)
{
auto x = std::chrono::steady_clock::now() + std::chrono::milliseconds(interval);
func();
std::this_thread::sleep_until(x);
}
}).detach();
}
void execute(void)
{
if(/*some special condition*/)
{
myClass.QuitFuncA();
}
if(myClass.isFuncInUse() == false)
{
// USE THE FUNCTION
myClass.FuncA();
}
}
void check(void)
{
if(myClass.isFuncInUse())
{
status = myClass.FuncB();
printf("STATUS %d\n", status?true:false);
}
}
int main(void)
{
timerStart(execute, 500);
timerStart(check, 500);
}
The problem is: FuncA sets funcInUse to true in one iteration. In the next iteration, funcInUse is false again, although it was not been reset by FuncB. What may happen that resets funcInUse between the two iterations?
I tried printing this when calling the three functions in MyClass and all of them had the same address. I also tried to use bind with the class methods as I learned previously from here but it didn't work.
I tried to use mutex, semaphore and condition variables but I faced the problem that FuncA should gain the mutex while FuncB should release it after making sure the sent command has been executed (which is not allowed with mutex). And in one condition, a function in MyClass should reset isFuncInUse. Is there a better way to synchronize between the two methods than using funcInUse variable?
Thank you

Terminating an std::thread which runs in endless loop

How can I terminate my spun off thread in the destructor of Bar (without having to wait until the thread woke up form its sleep)?
class Bar {
public:
Bar() : thread(&Bar:foo, this) {
}
~Bar() { // terminate thread here}
...
void foo() {
while (true) {
std::this_thread::sleep_for(
std::chrono::seconds(LONG_PERIOD));
//do stuff//
}
}
private:
std::thread thread;
};
You could use a std::condition_variable:
class Bar {
public:
Bar() : t_(&Bar::foo, this) { }
~Bar() {
{
// Lock mutex to avoid race condition (see Mark B comment).
std::unique_lock<std::mutex> lk(m_);
// Update keep_ and notify the thread.
keep_ = false;
} // Unlock the mutex (see std::unique_lock)
cv_.notify_one();
t_.join(); // Wait for the thread to finish
}
void foo() {
std::unique_lock<std::mutex> lk(m_);
while (keep_) {
if (cv_.wait_for(lk, LONG_PERIOD) == std::cv_status::no_timeout) {
continue; // On notify, just continue (keep_ is updated).
}
// Do whatever the thread needs to do...
}
}
private:
bool keep_{true};
std::thread t_;
std::mutex m_;
std::condition_variable cv_;
};
This should give you a global idea of what you may do:
You use an bool to control the loop (with protected read and write access using a std::mutex);
You use an std::condition_variable to wake up the thread to avoid waiting LONG_PERIOD.

Multithreaded Tasking System fails list iterator not derefercable

Okay this meight be a bit off for Stack but ill try to keep it as short as possible.
I got thread which takes tasks out of a list and executes them. Simple as this (The worker class has its own thread and runs doTask m_thread(&Worker::doTask, this)):
void Worker::doTask()
{
while (m_running)
{
auto task = m_tasks.pop_front();
task->execute();
if (task->isContinuous())
m_tasks.push_pack(task);
}
}
The list itself is/should be threadsafe:
Header:
class TaskQueue
{
public:
void push_pack(std::shared_ptr<Task> t);
std::shared_ptr<Task> pop_front();
private:
std::list<std::shared_ptr<Task>> m_tasks;
std::condition_variable m_cond;
std::mutex m_mutex;
void TaskQueue::push_pack(std::shared_ptr<Task> t)
}
Impls of the importand part:
void TaskQueue::push_pack(std::shared_ptr<Task> t)
{
m_tasks.push_back(t);
//notify that there is one more task, so one thread can work now
m_cond.notify_one();
}
std::shared_ptr<Task> TaskQueue::pop_front()
{
//regular lock so noone else acces this area now
std::unique_lock<std::mutex> lock(m_mutex);
while (m_tasks.size() == 0)
m_cond.wait(lock);
auto task = m_tasks.front();
m_tasks.pop_front();
return task;
}
last but not least the tasks:
class Task
{
public:
virtual ~Task()
{
}
virtual void execute() = 0;
virtual bool isContinuous()
{
return false;
};
};
So if i try to add this Task:
class NetworkRequestTask:public Task
{
public:
NetworkRequestTask(TaskQueue &q);
~NetworkRequestTask();
void execute() override;
bool isContinuous() override;
private:
TaskQueue &m_tasks;
};
Impl:
NetworkRequestTask::NetworkRequestTask(TaskQueue& q): m_tasks(q)
{
}
NetworkRequestTask::~NetworkRequestTask()
{
}
void NetworkRequestTask::execute()
{
while(dosomething)
{
//do something here
}
}
bool NetworkRequestTask::isContinuous()
{
return true;
}
Main:
int main(int argc, char* argv[])
{
TaskQueue tasks;
tasks.push_pack(std::make_shared<NetworkRequestTask>(tasks));
}
it gets into a bad state:
Expression: list iterator not derefercable
I am Confused. This only happens if i override continouse and this only happens at this task. If i add the queue to a other continouse task as reference it does not get into that bad state.
So whats going wrong here and more importand what have i done wrong?
As from the comments, i already tried to lock the push_back method which did not change anything to the behaviour. (You can exchange it for a regular mutex it doesnt matter.)
void TaskQueue::push_pack(std::shared_ptr<Task> t)
{
std::lock_guard<SpinLock> lock(m_spin);
m_tasks.push_back(t);
//notify that there is one more task, so one thread can work now
m_cond.notify_one();
}

Threads in C++11

I'm updating my C++ skills to C++11. I'm up to threads, always a problem area. Consider this testing code:
// threaded.h
class MyThreadedClass
{
public:
MyThreadClass();
bool StartThread();
bool IsThreadDone();
inline void WorkThread();
private:
std::thread* workThread;
atomic<bool> threadDone;
}
// threaded.cpp
MyThreadedClass::MyThreadedClass() {
workThread = nullptr;
threadDone.store(true);
}
bool MyThreadedClass::StartThread() {
if (!threadDone.load()) { return false; }
threadDone.store(false);
workThread = new std::thread(&MyThreadedClass:WorkThread, this);
workThread->detach();
return true;
}
bool MyThreadedClass:IsThreadDone() {
return threadDone.load();
}
inline void MyThreadedClass::WorkThread() {
while (some_condition) { /*Do work*/ }
threadDone.store(true);
}
// main.cpp
int main() {
MyThreadedClass testInstance;
testInstance.StartThread();
for (int x = 0; x < 10; x++) {
do {
// This is sometimes true:
if (testInstance.StartThread()) { return 1;}
} while (!testInstance.IsThreadDone())
}
return 0;
}
I wanted to look at a worst case scenario for this type of code therefore I'm pounding it continually in main while waiting for thread to terminate. Sometimes the failure condition in main is triggered. As with many threading problems it's not consistent and therefore not easy to debug.
The threadDone variable is used because I access a file in my actual code and don't want multiple threads accessing the same file.
Insight into what I'm missing or ways to redesign this with C++11 idioms welcome.
With std::mutex instead of std::atomic, the implementation is quite simple.
class MyThreadedClass
{
std::mutex _mutex;
std::unique_ptr<std::thread> _thread;
bool _done{false};
public:
MyThreadClass() = default;
bool StartThread()
{
std::lock_guard<std::mutex> lock(_mutex);
if (_thread || _done) return false;
_thread = std::make_unique<std::thread>(&MyThreadedClass, this);
return true;
}
bool IsThreadDone()
{
std::lock_guard<std::mutex> lock(_mutex);
return _done;
}
void WorkThread()
{
// do some work
std::lock_guard<std::mutex> lock(_mutex);
_done = true;
}
}
The best reference / learning book I know of for C++11 concurrency is here: C++ Concurrency in Action: Practical Multithreading by Anthony Williams.
You have a race condition (though not a "data race") in your main() function, which I've transcribed, inlined, and simplified below:
void MyThreadedClass::WorkThread() {
threadDone.store(true);
}
int main() {
MyThreadedClass testInstance;
testInstance.threadDone.store(false);
new std::thread(&MyThreadedClass::WorkThread, &testInstance)->detach();
// This sometimes fails:
assert(!testInstance.threadDone.load());
return 0;
}
That assertion will fail if WorkThread happens to run to completion before the main thread is scheduled again. Since the standard doesn't constrain the scheduling, you'd need to write some code to block if you need the worker thread to wait.

Can I create a software watchdog timer thread in C++ using Boost Signals2 and Threads?

I am running function Foo from somebody else's library in a single-threaded application currently. Most of the time, I make a call to Foo and it's really quick, some times, I make a call to Foo and it takes forever. I am not a patient man, if Foo is going to take forever, I want to stop execution of Foo and not call it with those arguments.
What is the best way to call Foo in a controlled manner (my current environment is POSIX/C++) such that I can stop execution after a certain number of seconds. I feel like the right thing to do here is to create a second thread to call Foo, while in my main thread I create a timer function that will eventually signal the second thread if it runs out of time.
Is there another, more apt model (and solution)? If not, would Boost's Signals2 library and Threads do the trick?
You can call Foo on a second thread with a timeout. For example:
#include <boost/date_time.hpp>
#include <boost/thread/thread.hpp>
boost::posix_time::time_duration timeout = boost::posix_time::milliseconds(500);
boost::thread thrd(&Foo);
if (thrd.timed_join(timeout))
{
//finished
}
else
{
//Not finished;
}
You can use the following class:
class timer
{
typedef boost::signals2::signal<void ()> timeout_slot;
public:
typedef timeout_slot::slot_type timeout_slot_t;
public:
timer() : _interval(0), _is_active(false) {};
timer(int interval) : _interval(interval), _is_active(false) {};
virtual ~timer() { stop(); };
inline boost::signals2::connection connect(const timeout_slot_t& subscriber) { return _signalTimeout.connect(subscriber); };
void start()
{
boost::lock_guard<boost::mutex> lock(_guard);
if (is_active())
return; // Already executed.
if (_interval <= 0)
return;
_timer_thread.interrupt();
_timer_thread.join();
timer_worker job;
_timer_thread = boost::thread(job, this);
_is_active = true;
};
void stop()
{
boost::lock_guard<boost::mutex> lock(_guard);
if (!is_active())
return; // Already executed.
_timer_thread.interrupt();
_timer_thread.join();
_is_active = false;
};
inline bool is_active() const { return _is_active; };
inline int get_interval() const { return _interval; };
void set_interval(const int msec)
{
if (msec <= 0 || _interval == msec)
return;
boost::lock_guard<boost::mutex> lock(_guard);
// Keep timer activity status.
bool was_active = is_active();
if (was_active)
stop();
// Initialize timer with new interval.
_interval = msec;
if (was_active)
start();
};
protected:
friend struct timer_worker;
// The timer worker thread.
struct timer_worker
{
void operator()(timer* t)
{
boost::posix_time::milliseconds duration(t->get_interval());
try
{
while (1)
{
boost::this_thread::sleep<boost::posix_time::milliseconds>(duration);
{
boost::this_thread::disable_interruption di;
{
t->_signalTimeout();
}
}
}
}
catch (boost::thread_interrupted const& )
{
// Handle the thread interruption exception.
// This exception raises on boots::this_thread::interrupt.
}
};
};
protected:
int _interval;
bool _is_active;
boost::mutex _guard;
boost::thread _timer_thread;
// Signal slots
timeout_slot _signalTimeout;
};
An example of usage:
void _test_timer_handler()
{
std::cout << "_test_timer_handler\n";
}
BOOST_AUTO_TEST_CASE( test_timer )
{
emtorrus::timer timer;
BOOST_CHECK(!timer.is_active());
BOOST_CHECK(timer.get_interval() == 0);
timer.set_interval(1000);
timer.connect(_test_timer_handler);
timer.start();
BOOST_CHECK(timer.is_active());
std::cout << "timer test started\n";
boost::this_thread::sleep<boost::posix_time::milliseconds>(boost::posix_time::milliseconds(5500));
timer.stop();
BOOST_CHECK(!timer.is_active());
BOOST_CHECK(_test_timer_count == 5);
}
You can also set an alarm right before calling that function, and catch SIGALRM.
Vlad, excellent post! Your code compiled and works beautifully. I implemented a software watchdog timer with it. I made a few modifications:
To prevent pointer decay, store the signal in boost::shared_ptr and pass this to the thread worker instead of a weak pointer to the timer class. This eliminates the need for the thread worker to be a friend struct and guarantees the signal is in memory.
Add parameter _is_periodic to allow the caller to select whether or not the worker thread is periodic or if it terminates after expiration.
Store _is_active, _interval and _is_periodic in boost::atomic to allow thread-safe access.
Narrow the scope of mutex locking.
Add reset() method to "kick" the timer, preventing it from issuing the expiration signal.
With these changes applied:
#include <atomic>
#include <boost/signals2.hpp>
#include <boost/thread.hpp>
class IntervalThread
{
using interval_signal = boost::signals2::signal<void(void)>;
public:
using interval_slot_t = interval_signal::slot_type;
IntervalThread(const int interval_ms = 60)
: _interval_ms(interval_ms),
_is_active(false),
_is_periodic(false),
_signal_expired(new interval_signal()) {};
inline ~IntervalThread(void) { stop(); };
boost::signals2::connection connect(const interval_slot_t &subscriber)
{
// thread-safe: signals2 obtains a mutex on connect()
return _signal_expired->connect(subscriber);
};
void start(void)
{
if (is_active())
return; // Already executed.
if (get_interval_ms() <= 0)
return;
boost::lock_guard<boost::mutex> lock(_timer_thread_guard);
_timer_thread.interrupt();
_timer_thread.join();
_timer_thread = boost::thread(timer_worker(),
static_cast<int>(get_interval_ms()),
static_cast<bool>(is_periodic()),
_signal_expired);
_is_active = true;
};
void reset(void)
{
if (is_active())
stop();
start();
}
void stop(void)
{
if (!is_active())
return; // Already executed.
boost::lock_guard<boost::mutex> lock(_timer_thread_guard);
_timer_thread.interrupt();
_timer_thread.join();
_is_active = false;
};
inline bool is_active(void) const { return _is_active; };
inline int get_interval_ms(void) const { return _interval_ms; };
void set_interval_ms(const int interval_ms)
{
if (interval_ms <= 0 || get_interval_ms() == interval_ms)
return;
// Cache timer activity state.
const bool was_active = is_active();
// Initialize timer with new interval.
if (was_active)
stop();
_interval_ms = interval_ms;
if (was_active)
start();
};
inline bool is_periodic(void) const { return _is_periodic; }
inline void set_periodic(const bool is_periodic = true) { _is_periodic = is_periodic; }
private:
// The timer worker for the interval thread.
struct timer_worker {
void operator()(const int interval_ms, const bool is_periodic, boost::shared_ptr<interval_signal> signal_expired)
{
boost::posix_time::milliseconds duration(interval_ms);
try {
do {
boost::this_thread::sleep<boost::posix_time::milliseconds>(duration);
{
boost::this_thread::disable_interruption di;
signal_expired->operator()();
}
} while (is_periodic);
} catch (const boost::thread_interrupted &) {
// IntervalThread start(), stop() and reset() throws boost::this_thread::interrupt,
// which is expected since this thread is interrupted. No action neccessary.
}
};
};
std::atomic<int> _interval_ms; // Interval, in ms
std::atomic<bool> _is_active; // Is the timed interval active?
std::atomic<bool> _is_periodic; // Is the timer periodic?
boost::mutex _timer_thread_guard;
boost::thread _timer_thread;
// The signal to call on interval expiration.
boost::shared_ptr<interval_signal> _signal_expired;
};