Related
First and foremost, I understand that formally, using a non-atomic flag to cancel a thread is very much undefined behaviour in the sense that the language does not specify if this variable will be written to before the thread exits.
At work, this was implemented a long time ago, and most calculation threads check the value of this bool throughout their work, as to gracefully cancel whatever it is they're doing. When I first saw this, my first reaction was to change all of this to use a better way (in this case, QThread::requestInterruption and QThread::interruptionRequested seemed like a viable alternative). A quick search through the code turned up about 800 occurences of this variable/construct throughout the codebase, so I let it go.
When I approached a (senior, in terms of years of experience) colleague, he assured me that although it might indeed be wrong, he had never seen it fail to fulfill its purpose. He argued that the only case it would go wrong is if a (group of) thread(s) is allowed to run and another thread that actually changes this flag never gets allowed to execute untill the other threads are finished. He also argued that in this case, the OS would intervene and fairly distribute runtime across all threads, resulting in perhaps a delay of the cancellation.
Now my question is: is there any real-life situation (preferably on a regular system, based upon x86/ARM, preferably C or C++) where this does indeed fail?
Note I'm not trying to win the argument, as my colleague agrees it is technically incorrect, but I would like to know if it could cause problems and under which circumstances this might occur.
The simplest way to beat this is to reduce it to a rather trivial example. The compiler will optimize out reading the flag because it is not atomic and being written to by another thread is UB; therefore the flag won't ever get actually read.
Your colleague's argument is predicated on the assumption that the compiler will actually load the flag when you de-reference the flag. But in fact it has no obligation to do so.
#include <thread>
#include <iostream>
bool cancelled = false;
bool finished = false;
void thread1() {
while(!cancelled) {
std::cout << "Not cancelled";
}
}
int main() {
std::thread t(thread1);
t.detach();
cancelled = true;
while(!finished) {}
}
To run on coliru, load http://coliru.stacked-crooked.com/a/5be139ee34bf0a80, you will need to edit and make a trivial change because the caching is broken for snippets that do not terminate.
Effectively, he's simply betting that the compiler's optimizer will do a poor job, which seems like a truly terrible thing to rely upon.
As long as you wait for the threads to finish before using their data, you'll be OK in practice: the memory barriers set by std::thread::join or QThread::wait will protect you.
Your worry isn't about the cancelled variable, as long as it's volatile you're in practice fine. You should worry about reading inconsistent state of the data modified by the threads.
As can be inferred from Mine's comment, Puppy's code example does not demonstrate the problem. A few minor modifications are necessary.
Firstly, we must add finished = true; at the end of thread1 so that the program even pretends to be able to terminate.
Now, the optimizer isn't able to check every function in every translation unit to be sure that cancelled is in fact always false when entering thread1, so it cannot make the daring optimization to remove the while loop and everything after it. We can fix that by setting cancelled to false at the start of thread1.
With the previous addition, for fairness, we must also continually set cancelled to true in main, because otherwise we cannot guarantee that the single assignment in main is not scheduled after the initial assignment of in thread1.
Edit: Added qualifiers, and synchronous join instead of detachment.
#include <thread>
#include <iostream>
bool cancelled = false;
bool finished = false;
void thread1() {
cancelled = false;
while(!cancelled)
;
finished = true;
}
int main() {
std::thread t(thread1);
while(!finished) {
std::cout << "trying to cancel\n";
cancelled = true;
}
t.join();
}
I am new to multi-threading. I am using c++ on unix.
In the code below, runSearch() takes a long time and I want to be able to kill the search as soon as "cancel == true". The function cancelSearch is called by another thread.
What is the best way to solve this problem?
Thanks you..
------------------This is the existing code-------------------------
struct SearchTask : public Runnable
{
bool cancel = false;
void cancelSearch()
{
cancel = true;
}
void run()
{
cancel = false;
runSearch();
if (cancel == true)
{
return;
}
//...more steps.
}
}
EDIT: To make it more clear, say runSearch() takes 10 mins to run. After 1 min, cancel==true, then I want to exit out of run() immediately rather than waiting another 9 more mins for runSearch() to complete.
You'll need to keep checking the flag throughout the search operation. Something like this:
void run()
{
cancel = false;
while (!cancel)
{
runSearch();
//do your thread stuff...
}
}
You have mentioned that you cannot modify runSearch(). With pthreads there's a pthread_setcancelstate() function, however I don't believe this is safe, especially with C++ code that expects RAII semantics.
Safe thread cancellation must be cooperative. The code that gets canceled must be aware of the cancellation and be able to clean up after itself. If the code is not designed to do this and is simply terminated then your program will probably exhibit undefined behavior.
For this reason C++'s std::thread does not offer any method of thread cancellation and instead the code must be written with explicit cancellation checks as other answers have shown.
Create a generic method that accepts a action / delegate. Have each step be something REALLY small and specific. Send the generic method a delegate / action of what you consider a "step". In the generic method detect if cancel is true and return if true. Because steps are small if it is cancelled it shouldn't take long for the thread to die.
That is the best advice I can give without any code of what the steps do.
Also note :
void run()
{
cancel = false;
runSearch();
while (!cancel)
{
//do your thread stuff...
}
}
Won't work because if what you are doing is not a iteration it will run the entire thread before checking for !cancel. Like I said if you can add more details on what the steps do it would easier to give you advice. When working with threads that you want to halt or kill, your best bet is to split your code into very small steps.
Basically you have to poll the cancel flag everywhere. There are other tricks you could use, but they are more platform-specific, like thread cancellation, or are not general enough like interrupts.
And cancel needs to be an atomic variable (like in std::atomic, or just protected it with a mutex) otherwise the compiler might just cache the value in a register and not see the update coming from another thread.
Reading the responses is right - just because you've called a blocking function in a thread doesn't mean it magically turns into a non-blocking call. The thread may not interrupt the rest of the program, but it still has to wait for the runSearch call to complete.
OK, so there are ways round this, but they're not necessarily safe to use.
You can kill a thread explicitly. On Windows you can use TerminateThread() that will kill the thread execution. Sound good right? Well, except that it is very dangerous to use - unless you know exactly what all the resources and calls are going on in the killed thread, you may find yourself with an app that refuses to work correctly next time round. If runSearch opens a DB connection for example, the TerminateThread call will not close it. Same applies to memory, loaded dlls, and all they use. Its designed for killing totally unresponsive threads so you can close a program and restart it.
Given the above, and the very strong recommendation you not use it, the next step is to call the runSearch in a external manner - if you run your blocking call in a separate process, then the process can be killed with a lot more certainty that you won't bugger everything else up. The process dies, clears up its memory, its heap, any loaded dlls, everything. So inside your thread, call CreateProcess and wait on the handle. You'll need some form on IPC (probably best not to use shared memory as it can be a nuisance to reset that when you kill the process) to transfer the results back to your main app. If you need to kill this process, call ExitProcess on it's handle (or exit in Linux)
Note that these exit calls require to be called inside the process, so you'll need to run a thread inside the process for your blocking call. You can terminate a process externally, but again, its dangerous - not nearly as dangerous as killing a thread, but you can still trip up occasionally. (use TerminateProcess or kill for this)
I am using ZThreads to illustrate the question but my question applies to PThreads, Boost Threads and other such threading libraries in C++.
class MyClass: public Runnable
{
public:
void run()
{
while(1)
{
}
}
}
I now launch this as follows:
MyClass *myClass = new MyClass();
Thread t1(myClass);
Is it now possible to kill (violently if necessary) this thread? I can do this for sure instead of the infinite loop I had a Thread::Sleep(100000) that is, if it is blocking. But can I kill a spinning thread (doing computation). If yes, how? If not, why not?
As far as Windows goes (from MSDN):
TerminateThread is a dangerous function that should only be used in
the most extreme cases. You should call TerminateThread only if you
know exactly what the target thread is doing, and you control all of
the code that the target thread could possibly be running at the time
of the termination. For example, TerminateThread can result in the
following problems:
If the target thread owns a critical section, the critical section will not be released.
If the target thread is allocating memory from the heap, the heap lock will not be released.
If the target thread is executing certain kernel32 calls when it is terminated, the kernel32 state for the thread's process could be inconsistent.
If the target thread is manipulating the global state of a shared DLL, the state of the DLL could be destroyed, affecting other users of the DLL.
Boost certainly doesn't have a thread-killing function.
A general solution to the kind of question posted can be found in Herb Sutter article:
Prefer Using Active Objects Instead of Naked Threads
This permits you to have something like this (excerpt from article):
class Active {
public:
typedef function<void()> Message;
private:
Active( const Active& ); // no copying
void operator=( const Active& ); // no copying
bool done; // le flag
message_queue<Message> mq; // le queue
unique_ptr<thread> thd; // le thread
void Run() {
while( !done ) {
Message msg = mq.receive();
msg(); // execute message
} // note: last message sets done to true
}
In the active object destructor you can have then:
~Active() {
Send( [&]{ done = true; } ); ;
thd->join();
}
This solution promotes a clean thread function exist, and avoids all other issues related to an unclean thread termination.
It is possible to terminate a thread forcefully, but the call to do it is going to be platform specific. For example, under Windows you could do it with the TerminateThread function.
Keep in mind that if you use TerminateThread, the thread will not get a chance to release any resources it is using until the program terminates.
If you need to kill a thread, consider using a process instead.
Especially if you tell us that your "thread" is a while (true) loop that may sleep for a long period of time performing operations that are necessarily blocking. To me, that indicate a process-like behavior.
Processes can be terminated in a various number of ways at almost any time and always in a clean way. They may also offer more reliability in case of a crash.
Modern operating systems offer an array of interprocess communications facilities: sockets, pipes, shared memory, memory mapped files ... They may even exchange file descriptors.
Good OSes have copy-on-write mechanism, so processes are cheap to fork.
Note that if your operations can be made in a non-blocking way, then you should use a poll-like mechanism instead. Boost::asio may help there.
You can with TerminateThread() API, but it is not recommended.
More details at:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms686717(v=vs.85).aspx
As people already said, there is no portable way to kill a thread, and in some cases not possible at all. If you have control over the code (i.e. can modify it) one of the simplest ways is to have a boolean variable that the thread checks in regular intervals, and if set then terminate the thread as soon as possible.
Can't you do add something like below
do {
//stuff here
} while (!abort)
And check the flag once in a while between computations if they are small and not too long (as in the loop above) or in the middle and abort the computation if it is long?
Not sure of the other libraries but in pthread library pthread_kill function is available pthread_kill
Yes,
Define keepAlive variable as an int .
Initially set the value of keepAlive=1 .
class MyClass: public Runnable
{
public:
void run()
{
while(keepAlive)
{
}
}
}
Now, when every you want to kill thread just set the value of keepAlive=0 .
Q. How this works ?
A. Thread will be live until the execution of the function continuous . So it's pretty simple to Terminate a function . set the value of variable to 0 & it breaks which results in killing of thread . [This is the safest way I found till date] .
Not strictly related to C++, I am looking for more of a design patter or suggestion on how to approach this.
Say I have
class A
{
public:
void process();
void wait();
}
I will first call process(), which (duuh) does some processing and will then call wait(). The wait() function is supposed to wait for a notification and then exit. I already have the logic for the notification on a separate thread, but I'm not really sure what the best approach for this is.
What I thought of is:
void A::wait()
{
while ( _notificationOccured == false )
{
}
}
where _notificationOccured can be a bool member of A that will be changed by the notification. But, again, I'm not sure that this is the best approach. Any suggestions?
Pooling for a variable gives terrible performance, because pooling thread takes almost all CPU time. You need to use events or messages - this stuff is platform-specific. You can use some portable library for this, for example, Boost.
What you do is called busy waiting.
The are various techniques to do this better, the simplest would be to use a plain mutex with ncondition notification (win32/pthreads/boost).
Your current approach introduces a power-loop, which will kill the performance of the system you are running on. You should introduce a short sleep-time (10ms will suffice) to prevent that from happening. Better yet, use a library, like Boost (as #Nim suggested).
Btw, polling like you do is not all bad. In fact, that is what so-called spin-locks do. The idea is that a short time of polling is more efficient than locking if the expected wait-time is short.
Two options:
Semaphores
Conditions
Both are OS specific, boost has support for latter. There are other ways (such as atomic operations, but how these are exposed is compiler specific). IMHO, I would use one of the above.
I only know this from Windows, so I don't know if this translates easily to other plattforms.
In pseudo code:
Timer myTimer(1, MYEVENT); // elapses every second
SetTimer( myTimer ); // register timer with event loop
while( running )
{
if( GetEvent() == MYEVENT )
{
}
}
In Windows GetEvent() is called WaitForSingleObject(...)
According to the C++0x final draft, there's no way to request a thread to terminate. That said, if required we need to implement a do-it-yourself solution.
On the other hand boost::thread provides a mechanism to interrupt a thread in a safe manner.
In your opinion, what's the best solution? Designing your own cooperative 'interruption mechanism' or going native?
All the language specification says that the support isn't built into the language.
boost::thread::interrupt needs some support from the thread function, too:
When the interrupted thread next executes one of the specified interruption points (or if it is currently blocked whilst executing one)
i.e. when the thread function doesn't give the caller a chance to interrupt, you are still stuck.
I'm not sure what you mean with "going native" - there is no native support, unless you are spellbound to boost:threads.
Still, I'd use an explicit mechanism. You have to think about having enough interruption points anyway, why not make them explicit? The extra code is usually marginal in my experience, though you may need to change some waits from single-object to multiple-objects, which - depending on your library - may look uglier.
One could also pull the "don't use exceptions for control flow", but compared to messing around with threads, this is just a guideline.
Using native handle to cancel a thread is a bad option in C++ as you need to destroy all the stack allocated objects. This was the main reason they don't included a cancel operation.
Boost.Thread provides an interrupt mechanism, that needs to pool on any waiting primitive. As this can be expensive as a general mechanism, the standard has not included it.
You will need to implement it by yourself. See my answer here to a similar question on how to implement this by yourself. To complete the solution an interruption should be throw when interrupted is true and the thread should catch this interruption and finish.
Here is my humble implementation of a thread canceller (for C++0x).
I hope it will be useful.
// Class cancellation_point
#include <mutex>
#include <condition_variable>
struct cancelled_error {};
class cancellation_point
{
public:
cancellation_point(): stop_(false) {}
void cancel() {
std::unique_lock<std::mutex> lock(mutex_);
stop_ = true;
cond_.notify_all();
}
template <typename P>
void wait(const P& period) {
std::unique_lock<std::mutex> lock(mutex_);
if (stop_ || cond_.wait_for(lock, period) == std::cv_status::no_timeout) {
stop_ = false;
throw cancelled_error();
}
}
private:
bool stop_;
std::mutex mutex_;
std::condition_variable cond_;
};
// Usage example
#include <thread>
#include <iostream>
class ThreadExample
{
public:
void start() {
thread_ = std::unique_ptr<std::thread>(
new std::thread(std::bind(&ThreadExample::run, this)));
}
void stop() {
cpoint_.cancel();
thread_->join();
}
private:
void run() {
std::cout << "thread started\n";
try {
while (true) {
cpoint_.wait(std::chrono::seconds(1));
}
} catch (const cancelled_error&) {
std::cout << "thread cancelled\n";
}
}
std::unique_ptr<std::thread> thread_;
cancellation_point cpoint_;
};
int main() {
ThreadExample ex;
ex.start();
ex.stop();
return 0;
}
It is unsafe to terminate a thread preemptively because the state of the entire process becomes indeterminate after that point. The thread might have acquired a critical section prior to being terminated. That critical section will now never be released. The heap could become permanently locked, and so on.
The boost::thread::interrupt solution works by asking nicely. It will only interrupt a thread doing something thats interruptible, like waiting on a Boost.Thread condition variable, or if the thread does one of these things after interrupt is called. Even then, the thread isn't unceremoniously put through the meat grinder as, say, Win32's TerminateThread function does, it simply induces an exception, which, if you've been a well-behaved coder and used RAII everywhere, will clean up after itself and gracefully exit the thread.
Implementing a do-it-yourself solution makes the most sense, and it really should not be that hard to do. You will need a shared variable that you read/write synchronously, indicating whether the thread is being asked to terminate, and your thread periodically reads from this variable when it is in a state where it can safely be interrupted. When you want to interrupt a thread, you simply write synchronously to this variable, and then you join the thread. Assuming it cooperates appropriately, it should notice that that the variable has been written and shut down, resulting in the join function no longer blocking.
If you were to go native, you would not gain anything by it; you would simply throw out all the benefits of a standard and cross-platform OOP threading mechanism. In order for your code to be correct, the thread would need to shut down cooperatively, which implies the communication described above.
Its unsafe to terminate a thread, since you would have no control over the state of any data-structures is was working on at that moment.
If you want to interrupt a running thread, you have to implement your own mechanism. IMHO if you need that, your design is not prepared for multiple threads.
If you just want to wait for a thread to finish, use join() or a future.
My implementation of threads uses the pimpl idiom, and in the Impl class I have one version for each OS I support and also one that uses boost, so I can decide which one to use when building the project.
I decided to make two classes: one is Thread, which has only the basic, OS-provided, services; and the other is SafeThread, which inherits from Thread and has method for collaborative interruption.
Thread has a terminate() method that does an intrusive termination. It is a virtual method which is overloaded in SafeThread, where it signals an event object. There's a (static) yeld() method which the running thread should call from time to time; this methods checks if the event object is signaled and, if yes, throws an exception caught at the caller of the thread entry point, thereby terminating the thread. When it does so it signals a second event object so the caller of terminate() can know that the thread was safely stopped.
For cases in which there's a risk of deadlock, SafeThread::terminate() can accept a timeout parameter. If the timeout expires, it calls Thread::terminate(), thus killing intrusively the thread. This is a last-resource when you have something you can't control (like a third-party API) or in situations in which a deadlock does more damage than resource leaks and the like.
Hope this'll be useful for your decision and will give you a clear enough picture about my design choices. If not, I can post code fragments to clarify if you want.
I agree with this decision. For example, .NET allows to abort any worker thread, and I never use this feature and don't recommend to do this to any professional programmer. I want to decide myself, when a worker thread may be interrupted, and what is the way to do this. It is different for hardware, I/O, UI and other threads. If thread may be stopped at any place, this may cause undefined program behavior with resource management, transactions etc.