Self terminating thread. Use join or detach - c++

I have a state machine being processed within a std::thread. This state machine initializes a network connection, processes data, and upon the receipt of a certain message, needs to shut itself down. Using join in this fashion triggers the 'abort() has been called' exception. Is this one of the cases where a detached thread is appropriate.
#include <iostream>
#include <thread>
#include <atomic>
#include <memory>
class ThreadExample
{
public:
ThreadExample()
{
StartThread();
}
void StartThread()
{
//start thread;
run_thread = true;
the_thread = std::thread(&ThreadExample::ThreadFunction, this);
}
void ThreadFunction()
{
while (run_thread)
{
if (correct_message_found)
ShutdownThread();
else
ProcessMessage(); //example code to imitate network processing
//arbitrary wait. not relevant to the problem
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
//read in by some network connection
void ProcessMessage(/*some message data*/)
{
static int counter = 0;
if (counter == 3)
{
correct_message_found = true;
}
else
{
std::cout << "Waiting for the right message\n";
counter++;
}
}
void ShutdownThread()
{
run_thread = false;
if (the_thread.joinable())
the_thread.join();
}
private:
std::thread the_thread;
std::atomic_bool run_thread;
bool correct_message_found = false;
};
int main()
{
auto example = std::make_unique<ThreadExample>();
int data;
std::cin >> data;
}

The correct way to terminate a thread from inside itself is to simply return from the function the thread is executing:
void ThreadFunction()
{
while (run_thread)
{
if (correct_message_found)
return;
else
ProcessMessage(); //example code to imitate network processing
//arbitrary wait. not relevant to the problem
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
Calling join from within the thread that is supposed to be joined is an error, see the first error condition: https://en.cppreference.com/w/cpp/thread/thread/join
join means "wait for the given thread to finish, then continue on". You are telling a thread to wait until it itself is finished. So it can only end once it has already ended, which is clearly contradictory.
Where you should call join is in the destructor of ThreadExample. ThreadFunction uses members of ThreadExample, and ThreadExample also owns the std::thread object, so ThreadExample cannot be allowed to die while the thread is still running. In the code you show, you would run into that problem if you input something before the thread is done: ThreadExample is then destroyed, and with it the std::thread object living inside. If a std::thread is destroyed while joinable (i.e. with a non-detached thread still running) then std::terminate is called:
https://en.cppreference.com/w/cpp/thread/thread/%7Ethread

Related

As i have made the flag volatile at some point it value of flag should change. But it is waiting infinitely on t thread only

#include <iostream>
#include<thread>
#include <initializer_list>
#include <vector>
#include <future>
#include <time.h>
using namespace std;
class Gadget{
public:
Gadget(){
flag_ = false;
cout<<"Creating new Gadgets"<<endl;
}
void wait(){
while(flag_==false){
cout<<"waiting here...."<<endl;
this_thread::sleep_for(chrono::milliseconds(1000));
}
}
void wake(){
flag_ = true;
}
private:
volatile bool flag_;
};
I am trying to make two threads and one thread will sleep for 1 sec after checking the flag value. As i have made flag volatile it should change at some point. But the program is waiting infinitely.
int main() {
Gadget g;
thread t(&Gadget::wait,g);
thread s(&Gadget::wake,g);
t.join();
s.join();
cout<<"Ending the program "<<endl;
return 0;
}
volatile isn't for variables that are changed by the program itself. It's for variables that changes outside the program's control - like if it's directly connected to hardware.
Your main problem is however that you pass g by value so the two threads are working on different copies of your original g.
So, change to
std::atomic<bool> flag_;
and
thread t(&Gadget::wait, &g);
thread s(&Gadget::wake, &g);
Also worth mentioning: The two methods will not necessarily run in the order you start them, so waiting here.... may or may not show up.
Edit:
As mentioned in the comments: When waiting for a condition you should usually use a std::condition_variable. I've made an example of how that could look. I've also moved the starting of the threads into Gadget which makes it more obvious which object the thread is working on.
#include <chrono>
#include <condition_variable>
#include <iostream>
#include <mutex>
#include <thread>
#include <vector>
class Gadget {
public:
Gadget() { std::cout << "Creating new Gadget\n"; }
// new interface for starting threads
std::thread start_wait() { return std::thread(&Gadget::wait, this); }
std::thread start_wake() { return std::thread(&Gadget::wake, this); }
private:
void wait() {
std::unique_lock<std::mutex> ul(mutex_);
std::cout << "wait: waiting here...\n";
// Read about "spurious wakeup" to understand the below:
while(not flag_) cond_.wait(ul);
// or:
// cond_.wait(ul, [this] { return flag_; });
std::cout << "wait: done\n";
}
void wake() {
// simulate some work being done for awhile
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
{ // lock context start
std::lock_guard<std::mutex> lg(mutex_);
flag_ = true;
std::cout << "wake: notifying the waiting threads\n";
} // lock context end
// notify all waiting threads
cond_.notify_all();
}
std::condition_variable cond_;
std::mutex mutex_;
bool flag_ = false; // now guarded by a mutex instead
};
int main() {
Gadget g;
// start some waiting threads
std::vector<std::thread> threads(16);
for(auto& th : threads) th = g.start_wait();
// and one that wakes them up
auto th_wake = g.start_wake();
for(auto& th : threads) th.join();
th_wake.join();
std::cout << "Ending the program\n";
}

How to wait for multiple threads to finish (with c++11 threads)?

I'm trying to write a program which uses c++11 threads functionality in order to spawn multiple threads, the main thread must wait for each spawned thread to be finished, and all spawned threads must run in parallel. I've come up with the following approach:
#include <iostream>
#include <stdio.h>
#include <thread>
#include <condition_variable>
#include <mutex>
using namespace std;
class Producer
{
public:
Producer(int a_id):
m_id(a_id),
m_running(false),
m_ready(false),
m_terminate(false)
{
m_id = a_id;
m_thread = thread(&Producer::run, this);
while (!m_ready) {}
}
~Producer() {
terminate();
m_thread.join();
}
void wait() {
unique_lock<mutex> lock(m_waitForRunFinishMutex);
m_cond.wait(lock);
// avoid spurious wake up
if (m_running) {
wait();
}
lock.unlock();
cout << "wait exit " << m_id << endl;
}
void start() {
m_running = true;
m_cond.notify_all();
}
void terminate() {
start();
m_terminate = true;
}
void run() {
m_ready = true;
do {
unique_lock<mutex> lock(m_mutex);
while (!m_running) {
m_cond.wait(lock);
}
if (!m_terminate) {
cout << "running thread: " << m_id << endl;
}
m_running = false;
m_cond.notify_all();
} while (!m_terminate);
}
private:
int m_id;
bool m_running;
bool m_ready;
bool m_terminate;
thread m_thread;
mutex m_mutex;
mutex m_waitForRunFinishMutex;
condition_variable m_cond;
};
The program runs fine when testing with just one thread, i.e the following program:
int main()
{
Producer producer1(1);
producer1.start();
producer1.wait();
return 0;
}
Results in the following output:
running thread: 1
wait exit: 1
However if I test the program with 2 thread, e.g:
int main()
{
Producer producer1(1);
Producer producer2(2);
producer1.start();
producer2.start();
producer1.wait();
producer2.wait();
return 0;
}
I get the following output:
running thread: 2
running thread: 1
wait exit 1
It seems producer2 never get notified (in producer2.wait()), and therefore the program never finishes. Hopefully somebody can point out what I'm missing here.
Thanks everybody for the help in addressing the problem. Eventually the root cause of the problem is described in point (3) of the accepted answer. I've solved this by correcting the wait function as follows:
void wait() {
unique_lock<mutex> lock(m_waitForRunFinishMutex);
while (m_running) {
m_cond.wait(lock);
}
lock.unlock();
}
Here's a quick collection of issues from a glance.
wait() is recursive without unlocking its unique lock (as per the comment from Detonar)
while (!m_ready) {} Is not in a memory barrier (try compiling with some optimization and see what happens!)
If the worker thread completes before wait() is called; there is no check performed before waiting on the condition variable. Since the worker thread is complete; it will never get woken. Clearly you must check to see if the thread can get woken up within the mutex before waiting on the condition variable.

Can multiple threads join the same boost::thread?

pthreads has undefined behavior if multiple threads try to join the same thread:
If multiple threads simultaneously try to join with the same thread,
the results are undefined.
Is the same true for boost::threads? The documentation does not appears to specify this.
If it is undefined, then what would be a clean way for multiple threads to wait on one thread completing?
If it is undefined, then what would be a clean way for multiple threads to wait on one thread completing?
The clean way would be for that one thread to inform the others that it is complete. A packaged_task contains a future which can be waited on, which can help us here.
Here's one way of doing that. I have used std::thread and std::packaged_task, but you could use the boost equivalents just as well.
#include <thread>
#include <mutex>
#include <future>
#include <vector>
#include <iostream>
void emit(const char* msg) {
static std::mutex m;
std::lock_guard<std::mutex> l(m);
std::cout << msg << std::endl;
std::cout.flush();
}
int main()
{
using namespace std;
auto one_task = std::packaged_task<void()>([]{
emit("waiting...");
std::this_thread::sleep_for(std::chrono::microseconds(500));
emit("wait over!");
});
// note: convert future to a shared_future so we can pass it
// to two subordinate threads simultaneously
auto one_done = std::shared_future<void>(one_task.get_future());
auto one = std::thread(std::move(one_task));
std::vector<std::thread> many;
many.emplace_back([one_done] {
one_done.wait();
// do my thing here
emit("starting thread 1");
});
many.emplace_back([one_done] {
one_done.wait();
// do my thing here
emit("starting thread 2");
});
one.join();
for (auto& t : many) {
t.join();
}
cout << "Hello, World" << endl;
return 0;
}
expected output:
waiting...
wait over!
starting thread 2
starting thread 1
Hello, World
I ended up using a boost::condition_variable... roughly:
class thread_wrapper {
boost::mutex mutex;
boost::condition_variable thread_done_condition;
bool thread_done = false;
void the_func() {
// ...
// end of the thread
{
boost:unique_lock<boost::mutex> lock(mutex);
thread_done = true;
}
thread_done_condition.notify_all();
}
void wait_until_done() {
boost::unique_lock<boost::mutex> lock(mutex);
thread_done_condition.wait(lock, [this]{ return thread_done; });
}
}
Then multiple callers can safely call wait_until_done().
It strikes me now that something like the following would also have worked:
class thread_wrapper {
public:
thread_wrapper() : thread([this]() { this->the_func(); }) { }
void wait_until_done() {
boost::unique_lock<boost::mutex> lock(join_mutex);
thread.join();
}
private:
void the_func() {
// ...
}
boost::mutex join_mutex;
boost::thread thread;
}

Threaded timer, interrupting a sleep (stopping it)

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;
};

terminating a running boost thread

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