[Edit: (copied from a comment) As it turns out, the problem was elsewhere, but thank you all for your input.]
I have a shared container class which uses a single mutex to lock the push() and pop() functions, since I don't want to simultaneously modify the head and tail. Here's the code:
int Queue::push( WorkUnit unit )
{
pthread_mutex_lock( &_writeMutex );
int errorCode = 0;
try
{
_queue.push_back( unit );
}
catch( std::bad_alloc )
{
errorCode = 1;
}
pthread_mutex_unlock( &_writeMutex );
return errorCode;
}
When I run this in debug mode, everything is peachy. When I run in release mode, I get crashes at roughly the time when the driver program starts pushing and popping "simultaneously". Does the try/catch block immediately force an exit if it catches a std::bad_alloc exception? If so, should I enclose the remainder of the function in a finally block?
Also, is it possible that the slower debug mode only succeeds because my push() and pop() calls never actually occur at the same time?
In C++ we use Resource Acquisition Is Initialization (RAII) for guarding against exceptions.
Is this actually bombing after an exception? Far more likely from your snippet is that you just have bad synchronization in place. That starts with the name of your mutex: "writeMutex". This is not going to work if there is also a "readMutex". All reading, peeking and writing operations need to be locked by the same mutex.
Does the try/catch block immediately
force an exit if it catches a
std::bad_alloc exception?
No. If a std::bad_alloc is thrown inside the try {...} block, the code in the catch {...} block will fire.
If your program is actually crashing, then it seems like either your push_back call is throwing some exception other than bad_alloc (which isn't handled in your code), or the bad_alloc is being thrown somewhere outside the try {...} block.
By the way, are you sure you really want to use a try...catch block here?
plus
what does the pop look like
create a lock wrapper class that will automatically free the lock when it goes out of scope (as in RAII comment)
c++ does not have finally (thanks to mr stoustrop being stroppy)
i would catch std::exception or none at all (ducks head down for flame war). If u catch none then you need the wrapper
Regarding release/debug: Yes, you will often find race condition change between the two types of builds. When you deal with synchronization, your threads will run with different level of training. Well written threading will mostly run concurrently while poorly written threading the threads will in a highly synchronous manner relative to each other. All types of synchronization yield some level synchronous behavior. It as if synchronous and synchronization come from the same root word...
So yes, given the slightly different run-time performance between debug and release, those points where the threads synchronize can sometimes cause bad code to manifest in one type of build and not the other.
You need to use RAII
This basically means using the constructor/destructor to lock/unlock the resource.
This gurantees that the mutex will always be unlocked even when exceptions are around.
You should only be using one mutex for access to the list.
Even if you have a read only mutex that is used by a thread that only reads. That does not mean it is safe to read when another thread is updating the queue. The queue could be in some intermediate state caused by a thread calling push() while another thread is trying ti navigate an invlide intermediate state.
class Locker
{
public:
Locker(pthread_mutex_t &lock)
:m_mutex(lock)
{
pthread_mutex_lock(&m_mutex);
}
~Locker()
{
pthread_mutex_unlock(&m_mutex);
}
private:
pthread_mutex_t& m_mutex;
};
int Queue::push( WorkUnit unit )
{
// building the object lock calls the constructor thus locking the mutex.
Locker lock(_writeMutex);
int errorCode = 0;
try
{
_queue.push_back( unit );
}
catch( std::bad_alloc ) // Other exceptions may happen here.
{ // You catch one that you handle locally via error codes.
errorCode = 1; // That is fine. But there are other exceptions to think about.
}
return errorCode;
} // lock destructor called here. Thus unlocking the mutex.
PS. I hate the use of leading underscore.
Though technically it is OK here (assuming member variables) it is so easy to mess up that I prefer not to pre pend '' to idnetifiers. See What are the rules about using an underscore in a C++ identifier? for a whole list of rules to do about '' in identifier names.
Previous code sample with Locker class has a major problem:
What do you do when and if pthread_mutex_lock() fails?
The answer is you must throw an exception at this point, from constructor, and it can be caught.
Fine.
However,
According to c++ exception specs throwing an exception from a destructor is a no-no.
HOW DO YOU HANDLE pthread_mutex_unlock FAILURES?
Running code under any instrumentation software serves no purpose whatsoever.
You have to right code that works, not run it under valgrind.
In C it works perfectly fine:
pthread_cleanup_pop( 0 );
r = pthread_mutex_unlock( &mutex );
if ( r != 0 )
{
/* Explicit error handling at point of occurance goes here. */
}
But because c++ is a software abortion there just no reasonable way to deal with threaded coded failures with any degree of certainty. Brain-dead ideas like wrapping pthread_mutex_t into a class that adds some sort of state variable is just that - brain dead. The following code just does not work:
Locker::~Locker()
{
if ( pthread_mutex_unlock( &mutex ) != 0 )
{
failed = true; // Nonsense.
}
}
And the reason for that is that after pthread_mutex_unlock() returns this thread very well may be sliced out of cpu - preempted. That means that the .failed public variable will be still false. Other threads looking at it will get wrong information - the state variable says no failures, meanwhile pthread_mutex_unlock() failed. Even if, by some stroke of luck, these two statements run in one go, this thread may be preempted before ~Locker() returns and other threads may modify the value of .failed. Bottom line these schemes do not work - there is no atomic test-and-set mechanism for application defined variables.
Some say, destructors should never have code that fails. Anything else is a bad design. Ok, fine. I am just curious to see what IS a good design to be 100% exception and thread safe in c++.
Related
I have a worker thread that is constantly running, created & managed through a std::thread. At the top level of my worker thread, I have a try/catch block with a while loop inside it. If an exception leaks through to the top level of the thread, I catch it and store it in a std::exception_ptr, which is a member of the class that also owns the non-static thread function:
// In class header (inside class declaration)
std::exception_ptr m_threadException;
// In class CPP file
void MyClass::MyThreadFunction()
{
try {
while (true) {
// Do thread stuff
}
}
catch (std::exception const& e) {
m_threadException = std::current_exception();
}
}
Once the thread dies due to this kind of exception, my class (which is also primarily used by the main thread) doesn't know it yet. My plan was to add thread checkpoints to the start of all the class's main functions, like so:
void MyClass::SomethingMainThreadCalls()
{
if (m_threadException) {
std::rethrow_exception(m_threadException);
m_threadException = nullptr; // Somehow reset it back to null; not sure if this will work
}
// Do normal function stuff
}
Assuming this is even a good idea, there's a possible race condition between when my main thread is checking if the exception_ptr is null (when calling SomethingMainThreadCalls()) and when the worker thread assigns to it. I haven't found any information (haven't checked the C++11 draft yet) about whether or not this is inherently thread safe (guaranteed by the standard) or if I am responsible for thread synchronization in this case.
If the latter, is using std::atomic a good idea to keep it simple? Example:
std::atomic<std::exception_ptr> m_threadException;
Something like that? I'd be interested in recommendations and information on best practice here.
There is no special statement about exception_ptr with regards to its thread safety in the standard. As such, it provides the default standard guarantee: accessing separate instances are fine, accessing the same instance is not.
I would suggest using atomic<bool> instead (if for no other reason than that exception_ptr is not trivially copyable and therefore can't be put in an atomic<T>) to let the other code know that the exception_ptr has been set. You'll be fine so long as:
You set m_threadException before setting the flag
You read m_threadException after checking the flag
You use the appropriate load/store memory orders to set/check the flag. The defaults are fine
You only write m_threadException exactly once.
The standard doesn't specify what is the implementation of std::exception_ptr, so the thread safeness of std::exception_ptr is also unspecified.
just wrap the exception pointer with some lock and the code will be fine.
Just tried to do this, but std::atomic requires a trivially copyable type, std::exception_ptr is not. You should get compilation error as I do (when using MSVC VS2019, C++14).
Lets say we have block of code, we just cant modify it, but we want to break it, exit this piece of code when it runs too long (x miliseconds)
Pseudo code
Throw exception after (500ms) {
auto result = Do some risky job, for example test string by regex with catastrophic backtracking risk.
}
catch ( Exception e ) {
//...
}
Every thing has to be still in the same thread.
Is it possible with c++11 or with some other standard?
In general, C++ does not have a way to induce an exception to be thrown in code without having code that throws an exception in the code, or in code that code calls.
You could embed an ASL, a scripting language, or a separate process. All 3 could be designed to be interrupted (processes, for example, can be killed).
Boost has interruptable threads. How it works is that it has hooks in the boost synchronization primitives (mutexes etc), so when you interact with them it checks if your thread has been told to halt. If so, it then throws an exception.
An easy, partial solution is to
std::vector<std::future<R()>> futures;
futures.push_back( std::async( std::launch::async, []()->R{ /* code */ ) );
using std::chrono::literals;
if (futures.back().wait_for(500ms)==std::future_status::ready) {
auto r = futures.back().get();
futures.pop_back();
clear_ready_futures(futures); // wait for 0ms and if so, discard and destroy
return r;
}
// failed case
here our futures stores the defunct futures (threads, in effect). clear_ready_futures cleans any old ones that have finished.
Tasks that have started will still run to completion, stealing cpu, but the calling code does not have to wait for them.
FreeBSD (as well as all other linux types) have "SigAlarm": Reference here
This will allow you to set up a timer; and when the event is triggered, your current code is interrupted, and signal handler called, setup by your previous call to signal
This will allow you to set a flag, which your ohh so very risky thread can check against; and then throw if required.
It won't allow you to raise exceptions directly in the way you want, but it will allow you to keep the application single threaded.
Why would I use a unique_lock<> wrapper?
I sometimes see code like this
std::unique_lock<std::mutex> lock(m_active_sessions_guard); // lock() the associated mutex
m_active_sessions[request_id] = session;
lock.unlock();
where a unique_lock<> is created just to lock the associated mutex.
Having searched, I've found that this class is not copyable. Is this the only benefit of using it?
unique_lock utilizes RAII to guarantee exception-safe code. Notice that C++ does not have a finally statement.
In the case a exception is thrown, the mutex will still be released correctly.
Consider this code:
int func()
{
m_active_sessions_guard.lock();
... some code ...
if (x > y)
{
return -1;
}
... some more code ...
m_active_sessions_guard.unlock();
return 1;
}
We "forgot" the unlock in the early return when x > y is true. This could deadlock our program, or (worse!) cause the program to run slowly/misbehave in some other way.
By using a type that automatically unlocks the lock when the destructor is called, you are guaranteed that you don't "forget" to unlock the lock, EVER. I have certainly spent MANY hours looking for such problems, and I wouldn't wish it upon anyone - especially the ones where triggering the situation where it locks up or runs slow is only happening once in a while, so to even "catch" the failure you have to be lucky (maybe x > y only happens on Thursdays, in months without "r" and when the date is divisible by both 7 and 3. So if you are unlucky enough to get the bug report at the end of April, you'll be debugging for a while... :)
The basis is RAII ("Resource Allocation Is Initialization"), and it's the same logic as why you want to use std::vector rather than pointers and call new/delete yourself. Any time you can make the compiler do the job for you, you have a great benefit of "not having to remember". Computers programs, such as compilers, are very good at "remembering" things.
A code which handles the exceptions well is called an exception safe code? Is this correct?
From here: https://codereview.stackexchange.com/a/9759/11619
You use lock/unlock pairs for the mutex. This is not exception safe.
So I would create an object that will do the lock in the constructor
and unlock in the destructor then use this to lock your mutexs. This
will make your code more exception safe.
class MutexLocker
{
pthread_mutex_t& mutex;
MutextLocker(pthread_mutex_t& mutex)
: mutex(mutex)
{
pthread_mutex_lock(&mutex);
}
~MutexLocker()
{
pthread_mutex_unlock(&mutex);
}
};
In which way is the above shown code exception safe? I don't see any exception handling over there.
Or does exception safe code mean where we can "add" the exception handling? So, the above shown code can be made exception safe by adding exception handling, but it isn't now?
Exception Safety is not about handling exceptions, it is about guaranteeing a number of properties about the program even in the presence of exceptions.
You can usually speak about the exception safety level of a given method:
No Guarantee: this method is exception unsafe, that is no guarantee is made, at all.
Basic Exception Guarantee: in case of exception no resource is leaked and the classes involved are still usable (but their state is unspecified), that is no memory leak, no file handle leak, no mutex leak and the invariants of the instances involved are still verified.
Strong Exception Guarantee: in case of exception, all state is reversed to what it was prior to beginning. This is a transaction like semantic.
NoThrow Guarantee: this method does not throw, it always succeeds.
In general, the NoThrow Guarantee only applies to the simplest methods (ie .size() on a vector for example) and the Strong Exception Guarantee may be costly to implement (being able to revert the effect or operating on a copy of the state may not be cheap).
On the other hand, the Basic Exception Guarantee is just that: Basic. Without it, safely operating a program is just impossible, so this is the least guarantee that is acceptable. If you leak resources or leave classes in an unusable state, the program may not be able to operate further.
This is why there is such an emphasis on RAII whenever exceptions are mentionned. Because RAII guarantees automatic cleanup of resources (memory, mutexes, files) whatever the path execution (regular return or exception) it is particularly desirable. However, RAII itself is not sufficient.
Related: Herb Sutter's GotW entry about Exception Safety and Exception Specifications.
the MutexLocker destructor is always called, also when an exception was raised in the block where it was constructed.
that is what makes a construct using your MutexLocker exception safe.
You don't have to handle an exception to be exception safe. You just have to survive when an exception is thrown.
The MutexLocker helps you do this by unlocking the mutex when you leave the scope. It doesn't matter if you leave by a return statement or because an exception is thrown.
"Exception safe" is a fairly overloaded term, but I would use it to describe sections of code which can have exceptions thrown through them and still maintain certain invariants (such as - nothing changes, no resources are leaked, all objects keep a valid state).
As an example, your void * printHello (void* threadId) function is correct (in that it always matches pthread_mutex_lock (&demoMutex) with pthread_mutex_unlock (&demoMutex)), but if someone changed the section in the middle so that it could throw an exception (for example, by setting the throw flags on std::cout), then your code would then permanently lock demoMutex, with no hope for it ever being released. This would constitute a bug in your program. void * printHello (void* threadId) is said to be "exception unsafe" because of this way in which bugs can easily be introduced into your program by adding exception handling to seemingly unrelated parts.
Using a RAII class to manage resources a good way to go about writing exception safe code (and is the resource management style to use in C++), because it avoids the need for duplicate manual cleanup in catch(...) blocks, and it enforces the cleanup of resources by using the type system.
A code which handles the exceptions well is called an exception safe code?
Yes, but you do not say what well is. This is a good read on exception safety.
In which way is the above shown code exception safe?
That code is not exception safe in itself. That is meant to be used in a exception safe code. For example :
void bar()
{
throw std::runtime_error( "lala" );
}
void foo()
{
pthread_mutex_lock(&mutex);
bar();
// OPS! mutex not unlocked
pthread_mutex_unlock(&mutex);
}
This problem is solved by using the class that automatically unlock the exception. Next example has exception handling with strong guarantees :
void foo()
{
MutexLocker locker( mutex );
try {
bar();
} catch ( const std::runtime_error & )
{
// revert changes
}
}
The code you provided serves the purpose well. Simply because when execution leaves the block in which the MutexLocker object is defined, the object is destroyed and the mutex is released as per its destructor. This holds no matter the reason for the exit.
You don't have to code this class yourself though. The C++ standard specifies a class named lock_guard that does exactly that.
http://en.cppreference.com/w/cpp/thread/lock_guard
I've written a Windows program in C++ which at times uses two threads: one background thread for performing time-consuming work; and another thread for managing the graphical interface. This way the program is still responsive to the user, which is needed to be able to abort a certain operation. The threads communicate via a shared bool variable, which is set to true when the GUI thread signals the worker thread to abort. Here is the code which implements this behaviour (I've stripped away irrelevant parts):
CODE EXECUTED BY THE GUI THREAD
class ProgressBarDialog : protected Dialog {
/**
* This points to the variable which the worker thread reads to check if it
* should abort or not.
*/
bool volatile* threadParameterAbort_;
...
BOOL CALLBACK ProgressBarDialog::DialogProc( HWND dialog, UINT message,
WPARAM wParam, LPARAM lParam ) {
switch( message ) {
case WM_COMMAND :
switch ( LOWORD( wParam ) ) {
...
case IDCANCEL :
case IDC_BUTTON_CANCEL :
switch ( progressMode_ ) {
if ( confirmAbort() ) {
// This causes the worker thread to be aborted
*threadParameterAbort_ = true;
}
break;
}
return TRUE;
}
}
return FALSE;
}
...
};
CODE EXECUTED BY THE WORKER THREAD
class CsvFileHandler {
/**
* This points to the variable which is set by the GUI thread when this
* thread should abort its execution.
*/
bool volatile* threadParamAbort_;
...
ParseResult parseFile( ItemList* list ) {
ParseResult result;
...
while ( readLine( &line ) ) {
if ( ( threadParamAbort_ != NULL ) && *threadParamAbort_ ) {
break;
}
...
}
return result;
}
...
};
threadParameterAbort_ in both threads point to a bool variable declared in a structure which is passed to the worker thread upon creation. It is declared as
bool volatile abortExecution_;
My question is: do I need to use volatile here, and is the code above sufficient to ensure that the program is thread-safe? The way I've reasoned for justifying the use of volatile here (see this question for background) is that it will:
prevent the reading of *threadParameterAbort_ to use the cache and instead get the value from memory, and
prevent the compiler from removing the if clause in the worker thread due to optimization.
(The following paragraph is only concerned with the thread-safety of the program as such and does not, I repeat, does not involve claiming that volatile in any way provides any means of ensuring thread-safety.) As far as I can tell, it should be thread-safe as setting of a bool variable should in most, if not all, architectures be an atomic operation. But I could be wrong. And I'm also worried about if the compiler may reorder instructions such as to break thread-safety. But better be safe (no pun intended) than sorry.
EDIT:
A minor mistake in my wording made the question appear as if I was asking if volatile is enough to ensure thread-safety. This was not my intent -- volatile does indeed not ensure thread-safety in any way -- but what I meant to ask was if the code provided above exhibit the correct behaviour to ensure that the program is thread-safe.
You should not depend on volatile to guarantee thread safety, this is because even though the compiler will guarantee that the the variable is always read from memory (and not a register cache), in multi-processor environments a memory barrier will also be required.
Rather use the correct lock around the shared memory. Locks like a Critical Section are often extremely lightweight and in a case of no contention will probably be all implemented userside. They will also contain the necessary memory barriers.
Volatile should only be used for memory mapped IO where multiple reads may return different values. Similarly for memory mapped writes.
Wikipedia says it pretty well.
In C, and consequently C++, the
volatile keyword was intended to allow access to memory mapped devices allow uses of variables between setjmp allow uses of sig_atomic_t variables in signal handlers
Operations on volatile variables are
not atomic nor establish a proper
happens-before relationship for
threading. This is according to the
relevant standards (C, C++, POSIX,
WIN32), and this is the matter of fact
for the vast majority of current
implementations. The volatile
keyword is basically worthless as a
portable threading construct.
volatile is neither necessary nor sufficient for multithreading in C++. It disables optimizations that are perfectly acceptable, but fails to enforce things like atomicity that are needed.
Edit: instead of using a critical section, I'd probably use InterlockedIncrement, which gives an atomic write with less overhead.
What I'd normally do, however, is hook up a thread-safe queue (or deque) as the input to the thread. When you have something for the thread to do, you just put a packet of data describing the job into the queue, and the thread does it when it can. When you want the thread to shut-down normally, you put a "shutdown" packet into the queue. If you need an immediate abort, you use the deque instead, and put the "abort" command on the front of the deque. In theory, this has the shortcoming that it doesn't abort the thread until it finishes its current task. About all that means is that you want to keep each task to roughly the same size/latency range as the frequency with which you currently check the flag.
This general design avoids a whole host of IPC problems.
With regard to my answer to yesterday's question, no, volatile is unnecessary. In fact, multithreading here is irrelevant.
while ( readLine( &line ) ) { // threadParamAbort_ is not local:
if ( ( threadParamAbort_ != NULL ) && *threadParamAbort_ ) {
prevent the reading of *threadParameterAbort_ to use the cache and instead get the value from
memory, and
prevent the compiler from removing the if clause in the worker
thread due to optimization.
The function readLine is external library code, or else it calls external library code. Therefore, the compiler cannot assume there are any nonlocal variables it does not modify. Once a pointer to an object (or its superobject) has been formed, it might be passed and stored anywhere. The compiler can't track what pointers end up in global variables and which don't.
So, the compiler assumes that readLine has its own private static bool * to threadParamAbort_, and modifies the value. Therefore it's necessary to reload from memory.
Seems that the same use case is descibed here: volatile - Multithreaded Programmer's Best Friend by Alexandrescu. It states that exactly in this case (to create flag) volatile can be perfectly used.
So, yes exactly in this case code should be correct. volative will prevent both - reading from cache and prevent compiler from optimizing out if statement.
Ok, so you've been beaten up enough about volatile and thread safety!, but...
An example for your specific code (though a stretch and within your control) is the fact that you are looking at your variable several times in the one 'transaction':
if ( ( threadParamAbort_ != NULL ) && *threadParamAbort_ )
If for whatever reason threadParamAbort_ is deleted after the left hand side and before the right hand side then you will dereference a deleted pointer. Again, this is unlikely given you have control but is an example of what volatile and atomicity can't do for you.
While the other answers are correct, I also suggest you take a look at the "Microsoft specific" section of the MSDN documentation for volatile
I think it'll work fine (atomic or not) because you're only using it to cancel a background operation.
The main thing that volatile is going to do is prevent the variable being cached or retrieved from a register. You can be sure that it's coming from main memory.
So if I were you, yes I would define the variable as volatile.
I think it's best to assume that volatile is needed to ensure that the variable when written and then read by the other threads that they actually get the correct value for that variable as soon as possible and to ensure that IF is not optimised away (although I doubt it would be).