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.