terminating a running boost thread - c++

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

Related

Multithreads not behaving as expected

#include <iostream>
#include <thread>
#include <mutex>
using namespace std;
std::mutex g_m;
std::string messageGlobal = "";
void threadFunc() // run in the log thread
{
while (1)
{
g_m.lock();
if (messageGlobal != "")
{
// logging takes a long time
sleep(10000)
cout << messageGlobal << endl;
messageGlobal = "";
}
g_m.unlock();
}
}
// logging api
void log(const string& message)
{
g_m.lock();
messageGlobal = message;
g_m.unlock();
}
int main()
{
std::thread th(threadFunc);
log("Hello world!");
log("Hello World2!");
log("Hello World3!");
log("Hello World4!");
// Important work
th.join();
return 0;
}
New to threading here and I don't understand why only the last message is being printed.
The two threads here are main thread and an extra thread which runs permanently and outputs to the screen whenever there is a message to be printed.
Would appreciate if someone shows me where I went wrong.
Edit: the goal is for the code in "important code" to execute while the very long logging function takes place.
As other people suggested, you'd better use a queue to hold the messages and synchronize the access of the message queue between threads. However, here is a simple fix of your code here:
#include <iostream>
#include <thread>
#include <mutex>
using namespace std;
std::mutex g_m;
std::string messageGlobal = "";
bool g_all_done = false;
void threadFunc() // run in the log thread
{
while (1)
{
g_m.lock();
if (messageGlobal != "")
{
cout << messageGlobal << endl;
messageGlobal = "";
}
bool all_done = g_all_done;
g_m.unlock();
if (all_done) break;
}
}
// logging api
void log(const string& message)
{
bool logged = false;
do {
g_m.lock();
if (messageGlobal == "") {
messageGlobal = message;
logged = true;
}
g_m.unlock();
} while(!logged);
}
void all_done() {
g_m.lock();
g_all_done = true;
g_m.unlock();
}
int main()
{
std::thread th(threadFunc);
log("Hello world!");
log("Hello World2!");
log("Hello World3!");
log("Hello World4!");
all_done(); // this tells the print thread to finish.
th.join();
return 0;
}
Would appreciate if someone shows me where I went wrong.
You are wrong in assumption that threads would lock mutex in order, which is not guaranteed. So what happened that the same thread (main) locked the mutex multiple times and modified the message multiple times and second thread only had a chance to print the last message. To make it work you should make main thread to wait until message is emptied and only then to publish again, but most probably you should do that using condition variable as otherwise you would peg CPU doing this in code as written. And even better to create a queue of log messages and only wait when queue is full.
Note that you are missing condition for log thread to finish so th.join(); would hang.
Here is example on how it could work with single message:
std::mutex g_m;
std::condition_variable g_notifyLog;
std::condition_variable g_notifyMain;
bool g_done = false;
std::string messageGlobal = "";
void threadFunc() // run in the log thread
{
while (1)
{
std::lock_guard<std::mutex> lk( g_m );
g_notifyLog.wait( g_m, []() { return !messageGlobal.empty() || g_done; } );
if( g_done ) break;
cout << messageGlobal << endl;
messageGlobal = "";
g_notifyMain.notify_one();
}
}
// logging api
void log(const string& message)
{
std::lock_guard<std::mutex> lk( g_m );
g_notifyMain.wait( g_m, []() { return messageGlobal.empty(); } );
messageGlobal = message;
g_notifyLog.notify_one();
}
void stop_log()
{
std::lock_guard<std::mutex> lk( g_m );
g_done = true;
g_notifyLog.notify_one();
}
You didn't implement any mechanism that ensures that the threads operate interleaved. It is much more likely that the thread that unlocked mutex will be the one to lock it in the next moment as locking mutex/unlocking mutexes are fast operations unless sleep/wait is triggered.
Furthermore, the ThreadFunc is an endless loop. So it theoretically the program might just run the loop repeatedly without letting any execution of log to trigger.
You need to utilise std::condition_variable to signal between threads when data is available for logging and rewrite log method so it won't overwrite existing data-to-be-printed.

Self terminating thread. Use join or detach

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

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.

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

Twice disconnect: How would you deal with this situation

I have code which checks if smart card is inserted or removed:
void checkCard(void *p)
{
//...
while(true)
{
if (ReaderState1.dwEventState & SCARD_STATE_EMPTY)
{
// Smart card removed, call disconnect
disconnectCard(cardHandle);
}
else
{
// Smart card inserted do smth else
}
}
}
In main I call above thread:
int main()
{
...
if(establichContext(_hSC) == true)
{
// Start thread
_beginthread(checkCard, 0, NULL);
// Sleep
Sleep(1000000); // or some other logic which halts program for some time
// Disconnect from card and release context
disconnectCard(cardHandle);
releaseContext(_hSC);
}
}
My problem is if smart card was already removed - by the first code snippet (checkCard function), calling disconnectCard - second time as in main, fails. How would you deal with such situation?
disconnectCard - just uses SCardDisconnect method inside )http://msdn.microsoft.com/en-us/library/windows/desktop/aa379475(v=vs.85).aspx)
I would handle the disconnection from the checkCard thread only. You can do this by using a flag to control the while loop in your worker thread, then clear this flag from main to stop the thread when you want to stop checking the card. You can then disconnect the card as part of shutting the thread down.
For example:
#include <windows.h>
#include <process.h>
#include <iostream>
void checkCard(void *p)
{
bool &keepgoing = *((bool *) p);
while (keepgoing)
{
// do what you want with check card
std::cout << "checking card" << std::endl;
Sleep(2000);
}
// if card still connected disconnect
std::cout << "cleanly exited" << std::endl;
}
int main(void)
{
bool run = true;
_beginthread(checkCard, 0, &run);
Sleep(15000);
// clear this flag to tell the worker thread to stop
run = false;
// wait for worker thread to finish - could have worker set flag
// again so you can test it has finished card disconnect etc.
Sleep(2000);
// done.
std::cout << "finished" << std::endl;
return 0;
}
Is that the behaviour you're looking for?
Have a flag that you check and set in the disconnectCard function.
Like
void disconnectCard(someType someArgument)
{
static bool disconnected = false;
if (disconnected)
return; // Already disconnected
// ... Do stuff ...
disconnected = true;
}