The naming of this function seems like this is some complicated stuff going on. When exactly does one know that this is the way to go instead of doing something like this:
Preparation
CRITICAL_SECTION cs;
int *p = malloc(sizeof(int)); // Allocation Site
InitializeCriticalSection(&cs); // HINT for first Write
Thread #1
{
*p = 1; // First Write
}
Thread #2
{
EnterCriticalSection(&cs);
*p = 2; // Second Write
LeaveCriticalSection(&cs);
}
I have a write that gets done in one thread:
Run()
{
// some code
m_bIsTerminated = TRUE;
// some more code
}
Then, I have a read that gets done in another thread (potentially at the same time):
Terminate()
{
// some code
if( m_bIsTerminated )
{
m_dwThreadId = 0;
m_hThread = NULL;
m_evExit.SetEvent();
return;
}
// even more code
}
What’s the best solution to solve this race condition? Are critical sections the way to go or is the use of InterlockedExchangeAdd() more useful?
InterlockedExchangeAdd is used to add a value to an integer as an atomic operation, meaning that you won’t have to use a critical section. This also removes the risk of a deadlock if one of your threads throws an exception – you need to make sure that you don’t keep any lock of any kind as that would prevent other threads from acquiring that lock.
For your scenario you can definitely use an Interlocked…- function, but I would use an event (CreateEvent, SetEvent, WaitForSingleObject), probably because I often find myself needing to wait for more than one object (you can wait for zero seconds in your scenario).
Upd: Using volatile for the variable may work, however it isn’t recommended, see: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2016.html and http://www-949.ibm.com/software/rational/cafe/blogs/ccpp-parallel-multicore/tags/c%2B%2B0x for instance.
If you want to be portable, take a look at boost::thread.