victor louis wrote:
Race conditions are among the most common classes of bugs found in deployed software. They are only possible in environments in which there are multiple threads or processes occurring at once that may potentially interact (or some other form of asynchronous processing, such as with UNIX signals). People who have experience with multithread programming have almost certainly had to deal with race conditions, regardless of whether they know the term.


A race condition can happen, even on a single processor computer. It's less likely, but any time that you can not guarantee when your thread/process will be context switched out for another you can't guarantee that another one of your own threads won't run before your first thread get CPU time back. This of course means that you need to address race conditions and prevent multiple entrance into critical sections, etc from occuring. Of course this all seems "at once" to a user but is far from it in terms of performance.

victor louis wrote:
They are often difficult to fix, even when you are aware of their existence. Race conditions are one of the few places where a seemingly deterministic program can behave in a seriously nondeterministic way. In a world where multithreading, multiprocessing, and distributed computing are becoming more and more prevalent, race conditions will continue to become a bigger and bigger problem.

Race conditions should be easy to fix, once you understand what the race condition is, there's many thread synchronization flags, locks, mutex, etc to deal with it. Anyone that has looked at general programming or database programming is familiar with the concepts from the reader/writer problem (also consumer/producer, and many other example situations).

Reader/Writer situation is that a prime example: you have a reader wanting to read a record and a writer wanting to write the same record. You can't just have them both working on the same record because you're not guaranteed that the reader won't end up with part of the old record and part of the new record. In fact you couldn't accurately predict what amount of new vs old data the reader would pick up. Solutions are varied and each have benefits and drawbacks. You can lock the record while it is being read (allowing multiple readers though) or being written (allow only one writer), this prevents corruption but causes wait times, etc. You can do a transactional system where anyone working with the set of data deals with the same version of the data which prevents the wait time but is harder to implement and means the reader will get old data and thus you need to handle the case where the reader might pass this data to a writer to be written.

Graphics is another area of race condition when performing calculations on different threads. This is where we get the idea of frame state, frame skipping, and such things to allow the processing to continue and still allow for the display to update.