I am kind of a newbie in Boost programming. What I want to do is create a thread from main() which will run continuously until the main() exits. Now, I am doing some operations on that thread and when it is done it will set a boolean flag. The main() will wait for this flag to be set, and when it is 'true' the main() will do its work, reset the flag, and wait for it to be set again. The other thread will run continuously.
Can anyone please provide a simple set of boost thread instructions to achieve this?
I am trying to do this in pseudocode
class Call {
public:
bool flag, do_it;
keyboard_callback() {
if('s' pressed) do_it = true;
}
f() { // some callback function
if(do_it == true) flag=true;
}
void func() {
...register callback f()
...register keyboard_callback()
...
while(some condition) { keep running , exit when 'q'}
...
}
};
main()
{
Call obj;
boost::thread th (boost::bind(&Call::func, &obj));
th.detach();
while(true) {
while (obj.flag == false);
...do something
}
}
// shared variables
boost::mutex mutex;
boost::condition_variable condition;
bool flag = false;
// signal completion
boost::unique_lock<boost::mutex> lock(mutex);
flag = true;
condition.notify_one();
// waiting in main method
boost::unique_lock<boost::mutex> lock(mutex);
while (!flag) {
condition.wait(lock);
}
Related
I was trying to write some Task-Management class with C++ boost::threadpool, condition_variable and mutex. It seems the program will stop at boost::threadpool::pool::wait(), but I don't know why this happens.
#include <boost/threadpool.hpp>
#include <condition_variable>
#include <iostream>
#include <mutex>
using namespace std;
enum {
Running,
Stopped,
Exiting
};
class C {
private:
int m_iStatus;
mutex m_mtx;
condition_variable m_cond;
boost::threadpool::pool m_tp;
public:
C() : m_iStatus(Stopped), m_tp(8) {}
void Start();
void Exit();
private:
bool Check();
void Dispatcher();
};
bool C::Check()
{
unique_lock<mutex> lk(m_mtx);
if (m_iStatus == Stopped)
m_cond.wait(lk);
if (m_iStatus == Exiting)
return false;
else
return true;
}
void C::Dispatcher()
{
if (!Check())
return;
unique_lock<mutex> lk(m_mtx);
// do something...
cout << "." << endl;
m_tp.schedule(bind(&C::Dispatcher, this));
}
void C::Start()
{
unique_lock<mutex> lk(m_mtx);
m_iStatus = Running;
m_tp.schedule(bind(&C::Dispatcher, this));
}
void C::Exit()
{
unique_lock<mutex> lk(m_mtx);
m_iStatus = Exiting;
m_cond.notify_all(); /* notify those waiting on m_cond */
m_tp.wait(); /* went wrong here */
}
int main()
{
C c;
c.Start();
/* wait for a moment */
Sleep(1000);
/* then call Exit */
c.Exit();
return 0;
}
You enter the wait call while still holding the mutex. This will prevent other thread's from completing their work.
In your particular case, the m_cond condition variable is waiting on that same mutex, so the call to m_cond.wait(lk); will be unable to return as long as the mutex is still being held by the other thread.
One solution to this would be to relinquish the lock on the mutex between notifying the condition variable and waiting for the thread pool to complete:
{
unique_lock<mutex> lk(m_mtx);
m_iStatus = Exiting;
m_cond.notify_all(); /* notify those waiting on m_cond */
} // lock on m_mtx gets released here
m_tp.wait(); /* this should run fine now */
I detach a thread from Class B:
t1 = std::thread(&Class::method, this);
t1.detach();
which as part of it's normal operation waits on a condition variable:
cv.wait(lock);
However, when I close my B application the detached thread remains. How do I stop/clean-up this thread when B::~B() is called?
Try this snippet: Set bool member variable discard_ to true to avoid execution of your scheduled process execution:
std::thread([&](){
std::lock_guard<std::mutex> lock(mutex_);
cv.wait(lock,[](){ return normal_predicate_here || discard_ ;});
if(discard_) return;
// execute scheduled process
}).detach();
Make the other thread cooperate for termination. Non-detached thread makes it easier to terminate cleanly, so that you do not destroy the state accessed by the other thread prematurely:
struct OtherThread {
std::mutex m_;
std::condition_variable c_;
bool stop_ = false;
std::thread t_;
void thread_function() {
for(;;) {
std::unique_lock<std::mutex> l(m_);
while(!stop_ /* || a-message-received */)
c_.wait(l);
if(stop_)
return;
// Process a message.
// ...
// Continue waiting for messages or stop.
}
}
~OtherThread() {
this->stop();
}
void stop() {
{
std::unique_lock<std::mutex> l(m_);
if(stop_)
return;
stop_ = true;
}
c_.notify_one();
t_.join(); // Wait till the thread exited, so that this object can be destroyed.
}
};
I have a singleton class which looks something like:
//Test.h
class Test
{
private:
static std::mutex mtx;
static std::condition_variable cv;
static bool end;
static void DoSomethingThread();
static void SomeOtherFunction();
public:
static void Start();
}
//Test.cpp
std::mutex Test::mtx;
std::condition_variable Test::cv;
bool Test::end = false;
void Test::Start()
{
std::thread t_thread(Test::DoSomethingThread);
while(a) {
if (b) {
// End thread.
std::unique_lock<std::mutex> lock(mtx);
Test::end = true;
Test::cv.notify_one();
t_thread.join();
Test::SomeOtherFunction();
// Restart thread.
Test::end = false;
t_thread = std::thread(Test::DoSomethingThread);
}
...
}
}
void Test::DoSomethingThread()
{
std::unique_lock<std::mutex> lock(mtx);
while (1) {
//Do some work here.
Test::cv.wait_for(lock, std::chrono::seconds(1000), []() { return Test::end; });
if (Test::end) { break; }
}
}
I found this code on this page and to be honest dont really know how this works. But the guy had the same problem as me and I thought it would work for my case to, but it didnt.
So what I currently have is have a thread t_thread which runs forever, it does some work and then sleeps for 1000 seconds and all over again. What I need is some way to wake this thread up from sleep and exit it. So SomeOtherFunction() can do its work and then restart the thread.
Why doesnt this code works, and how can I make it work?
I went back to original post and did:
if (b) {
{
// End thread.
std::unique_lock<std::mutex> lock(mtx);
Test::end = true;
Test::cv.notify_one();
}
t_thread.join();
Test::SomeOtherFunction();
// Restart thread.
Test::end = false;
t_thread = std::thread(Test::DoSomethingThread);
}
And it works now. Thanks anyway.
I'm wanting a reasonably reliable threaded timer, so I've written a timer object that fires a std::function on a thread. I would like to give this timer the ability to stop before it gets to the next tick; something you can't do with ::sleep (at least I don't think you can).
So what I've done is put a condition variable on a mutex. If the condition times out, I fire the event. If the condition is signalled the thread is exited. So the Stop method needs to be able to get the thread to stop and/or interrupt its wait, which I think is what it's doing right now.
There are problems with this however. Sometimes the thread isn't joinable() and sometimes the condition is signalled after its timeout but before it's put into its wait state.
How can I improve this and make it robust?
The following is a full repo. The wait is 10 seconds here but the program should terminate immediately as the Foo is created and then immediately destroyed. It does sometimes but mostly it does not.
#include <atomic>
#include <thread>
#include <future>
#include <sstream>
#include <chrono>
#include <iostream>
class Timer
{
public:
Timer() {}
~Timer()
{
Stop();
}
void Start(std::chrono::milliseconds const & interval, std::function<void(void)> const & callback)
{
Stop();
thread = std::thread([=]()
{
for(;;)
{
auto locked = std::unique_lock<std::mutex>(mutex);
auto result = terminate.wait_for(locked, interval);
if (result == std::cv_status::timeout)
{
callback();
}
else
{
return;
}
}
});
}
void Stop()
{
terminate.notify_one();
if(thread.joinable())
{
thread.join();
}
}
private:
std::thread thread;
std::mutex mutex;
std::condition_variable terminate;
};
class Foo
{
public:
Foo()
{
timer = std::make_unique<Timer>();
timer->Start(std::chrono::milliseconds(10000), std::bind(&Foo::Callback, this));
}
~Foo()
{
}
void Callback()
{
static int count = 0;
std::ostringstream o;
std::cout << count++ << std::endl;
}
std::unique_ptr<Timer> timer;
};
int main(void)
{
{
Foo foo;
}
return 0;
}
See my comment. You forgot to implement the state of the thing the thread is waiting for, leaving the mutex nothing to protect and the thread nothing to wait for. Condition variables are stateless -- your code must track the state of the thing whose change you're notifying the thread about.
Here's the code fixed. Notice that the mutex protects stop, and stop is the thing the thread is waiting for.
class Timer
{
public:
Timer() {}
~Timer()
{
Stop();
}
void Start(std::chrono::milliseconds const & interval,
std::function<void(void)> const & callback)
{
Stop();
{
auto locked = std::unique_lock<std::mutex>(mutex);
stop = false;
}
thread = std::thread([=]()
{
auto locked = std::unique_lock<std::mutex>(mutex);
while (! stop) // We hold the mutex that protects stop
{
auto result = terminate.wait_for(locked, interval);
if (result == std::cv_status::timeout)
{
callback();
}
}
});
}
void Stop()
{
{
// Set the predicate
auto locked = std::unique_lock<std::mutex>(mutex);
stop = true;
}
// Tell the thread the predicate has changed
terminate.notify_one();
if(thread.joinable())
{
thread.join();
}
}
private:
bool stop; // This is the thing the thread is waiting for
std::thread thread;
std::mutex mutex;
std::condition_variable terminate;
};
I currently have a boost thread as such
class foo
{
private:
boost::shared_ptr<boost::thread> t;
public:
foo()
{
t = boost::make_shared<boost::thread>(&foo::SomeMethod,this);
}
void SomeMethod()
{
while(true)
{
.... //Does some work
boost::this_thread::sleep(boost::posix_time::milliseconds(5000)); //sleep for 5 seconds
}
}
void stopThread()
{
//Elegant and instant way of stopping thread t
}
}
I have read from this post that you have to define interruption points however I am not sure if I understand how that would fit in my scenario. I am looking for a safe elegant way that will ensure that thread t is terminated
You can't ever safely terminate a thread, you just need to tell it from the outside that it should stop. If you interrupt a thread, you don't know where you interrupted it and you could leave the system in an unknown state.
Instead of looping forever, you can check a variable (make sure it's thread safe though!) inside the thread's loop to see if the thread should exit. What I do in work threads is I have them wait on a condition variable, and then when there's work they wake up and do work, but when they're awake they also check the "shutdown" flag to see if they should exit.
A snippet of my code:
//-----------------------------------------------------------------------------
void Manager::ThreadMain() {
unique_lock<mutex> lock( m_work_mutex, std::defer_lock );
while( true ) {
lock.lock();
while( m_work_queue.empty() && !m_shutdown ) {
m_work_signal.wait( lock );
}
if( !m_work_queue.empty() ) {
// (process work...)
continue;
}
// quit if no work left and shutdown flag set.
if( m_shutdown ) return;
}
}
You could maybe get away with something like:
std::atomic<bool> stop_thread = false;
void SomeMethod()
{
while( !stop_thread )
{
.... //Does some work
boost::this_thread::sleep(boost::posix_time::milliseconds(5000)); //sleep for 5 seconds
}
}
void stopThread()
{
stop_thread = true;
// join thread (wait for it to stop.)
t->join();
}
And let me tell you, sometimes it isn't easy to make something safely exit. A few weeks ago I had a big struggle with threaded console input. I ended up having to handle raw windows console events and translating them into keystrokes myself, just so I could simultaneously intercept my custom shutdown event.
Use boost::thread interrupt()
#include <iostream>
#include <boost/thread.hpp>
#include <boost/chrono.hpp>
class Foo
{
private:
boost::shared_ptr<boost::thread> t;
public:
Foo()
{
t = boost::make_shared<boost::thread>(&Foo::SomeMethod, this);
}
void SomeMethod()
{
std::cout << "thread starts" << std::endl;
while(true) {
std::cout << "." << std::endl;
boost::this_thread::sleep(boost::posix_time::seconds(1));
}
}
void stopThread()
{
t->interrupt();
t->join();
std::cout << "thread stopped" << std::endl;
}
};
int main()
{
Foo foo;
boost::this_thread::sleep(boost::posix_time::seconds(5));
foo.stopThread();
return 0;
}
Execute it
# g++ f.cpp -lboost_thread && ./a.out
thread starts
.
.
.
.
.
thread stopped