today i had a nice conversation with a friend regarding multithreading. we were figuring out what is the relation between a race condtion and a data race.
first question was: is it possible to have race condition without having a data race? the answer is yes. example proving it:
// thread 1: cout << 1; // thread 2: cout << 2;
program is a classic race condition, as the output is either “12” or “21”. using cout from different threads is not a data race (though content of both writes may obviously interleave).
so the second question is: is a data race concept a subset of a race condition concept? or another way around: is it possible to have a data race without having a race condition? again the answer is yes! proof:
// global variable: int x; // thread 1: x = 1; // thread 2: x = 1 // main: joinThread1(); joinThread2(); cout << x;
there is a clear data race on “x”, but there is no race condition, as the output will always be “1”. of course it is a bit tricky here – program with data race has an undefined behavior, so we cannot be really certain of anything. in practice however, on modern desktop, this particular case works just fine.
a conclusion is that data race and race conditions are independent concepts. you can have either one, (at least theoretically) without having an other.