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, andprevent 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.