Question

As in C++11, it has been imported atomic, as you know in our old code which use windows event (CreateEvent/SetEvent) for thread synchronize. pseudo code as below.

thread A:

while(true)
{
    if(check event is set)
       break;
    else
       do stuff
}

thread B:

SetEvent() //ask thread A stop.

I would like to know whether in this condition. Is it ok use atomic which is more simple as below, is there anything that atomic bool can not replace event? Thanks in advance!

std::atomic<bool> bFlag = false;

thread A:

while(true)
{
    if(bFlag)
       break;
    else
       do stuff
}

thread B:

bFlag = true;

[Update]

To make question more clear, thread A will not write bFlag, it just read it to know when exit thread. thread B will write bFlag to notify thread A stop.

There is no performance consideration in solution.

Was it helpful?

Solution

Doing this could be part of a carefully crafted solution. You need to watch out for less obvious race conditions and the ABA Problem (if "do stuff" uses bFlag).

In the following when I say "bad" I mean "Could the two threads read/write or write/write to the same data at the same time?".

Would it be bad if "do stuff" began executing just nanoseconds after bFlag was set true?
What conditions could cause bFlag to become false again?
Would it be bad if "do stuff" did not run just nanoseconds after bFlag became false?
Is it bad if the program runs "do stuff" multiple times before bFlag is set false?

If you can answer these questions correctly there is no technical reason you could not do this, but it might be the easy route.

In most cases std::atomic is implemented with Atomic Compare And Swap(CAS) ( http://en.wikipedia.org/wiki/Compare-and-swap )CPU instruction and the MESI Protocol ( http://en.wikipedia.org/wiki/MESI_protocol ) will ensure cache coherency. I do not think there is anying preventing this from being implemented with OS level mutexes though. If this is not a performance bottleneck or performance is not a primary concern, using a mutex around bFlag and "do stuff" might be easier.

Another possible route is using std::futures to asynchronously "do stuff" from thread B. Using this you could treat "do stuff" as its own function and not need to worry about the gory details of threading. ( http://en.cppreference.com/w/cpp/thread/future )

** Edit ** I did not know that by event you meant a windows specific event. My answer still holds in he general case, but since I do not know the details of the windows SetEvent its semantics could change just about anything.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top