Ok, when you have like 2 threads, 1 writes into a variable and one reads from the same variable, when you are not synchronizing, what can happen? I know that if the variable is larger than 1 byte, that the reading thread can read a partly updated value because the writer thread was updating it on the same time. But can things like access violation happen in this scenario? And what other things can happen?
IIRC, on x86, memory accesses (both in and out) are atomic for aligned data (as long as the data fits entirely in the cache line).
Segmentation faults are strictly memory protection issues. As long as the program doesn't go off using memory that doesn't belong to it, the system won't crash it (at least not because of a segmentation fault). It can do whatever it wants with the memory that does belong to it. Race conditions can't be detected, anyway.
Well, ok, thanks, but then I got another question, because I can't seem to figure it out and first wanted to know if that could be the problem.
I have a class, which causes access violation exceptions when I use the "AddValue" function of it, which is used on another thread than the main thread. This is the function:
You have a race condition, there. When there's one thread reading and one thread writing, it's one thing, but that function first reads, then writes to size, then reads it again. An example execution:
1. Thread 0 reads and compares size.
2. Thread 1 reads and compares size.
3. Thread 1 increments size by first reading it again and then writing it back.
4. Thread 0 increments size by first reading it again and then writing it back.
5. size was incremented one time too many.
An even worse case:
1. Thread 0 reads half 0 of size.
2. Thread 1 reads half 0 of size.
3. Thread 0 reads half 1 of size.
4. Thread 1 reads half 1 of size.
(Comparison and increment skipped.)
5. Thread 0 writes half 0 of size.
6. Thread 1 writes half 0 of size.
7. Thread 1 writes half 1 of size.
8. Thread 0 writes half 1 of size.
9. size contains garbage.
Lock the function and any other place where the variable is used asynchronously.
Well, there is actually one thread using that function, and the other thread is using these 2 functions to read out (it's a template class, where the typename is dataType):
Ok, I have commented out any lines that uses this class (called Buffer btw). Now I have only this thread left that is doing this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
void SensorPanelWindow::sensorWorker(SensorBuffer* sensorBuffer, MeasuringDevice* device, bool* stopSign)
{
WaitTime wt(100);
mutex::scoped_lock lock(sensorBuffer->mutex, boost::defer_lock);
while (!(*stopSign))
{
lock.lock();
sensorBuffer->buffer.AddValue(device->GetValue());
lock.unlock();
wt.WaitForNextInterval(); //Wait for the next 100 milisecond interval
}
}
I have checked with breakpoints, that there is only one thread doing this.
Then how is it possible that a race condition occurs? (Maybe I'm getting the concept of a race condition wrong.)
Ok, I found the problem. I didn't know the destructor was called on Buffer objects which doesn't get initialized, which ofcourse trigger the default destructor. It kinda stupid because it needs to call the destructor ofcourse. Anyway, the destructor deletes the internal buffer pointer, and because the uninitialized Buffers used the default contructors which don't create a buffer, the buffer wasn't created, which leads to unexpected behavior.
I also not get why acces violation occurred when I clicked on the menubar, it was created right after Buffer.