class AtomicityExample {
decimal _value;
void SetValue(decimal value) {_value = value;}
decimal GetValue() {return _value;}
}
If the code is executed by many threads, the returned value of GetValue method may be not a value that was set by a SetValue.
What is even less know is that the order of the operations in C# may change, due to .net optimization. Consider following code:
class OrderExample {
decimal d1;
volatile decimal d2;
decimal d3;
void Assign(){
d1 = 1;
d2 = 2;
d3 = 3;
}
}
The assignment in a code above can happen in following ways:
d1 = 1; d2 = 2; d3 = 3;or
d1 = 1; d3 = 3; d2 = 2;or
d3 = 3; d1 = 1; d2 = 2;In other words volatile variable can be assigned only after d1 was assigned, but when exactly depends on a compiler. Be aware that majority of programmers don't even use volatile keyword, and without volatile keyword reads/writes of variables above can happen in any order. And it matters, because I've seen so many times a code that looked like:
class FalseSecurityExample {
decimal d1;
bool assigned;
void Assign(){
d1 = 1;
assigned = true;
}
decimal Calculate(){
if(assigned){
return d1;
}
}
}
It means that in an example above d1 may not be set before it is returned, and if you add to a consideration fact that decimal is not atomic, you can expect anything to be returned by this code.
When I ask people why do they write such code, and if they are aware of issues that are illustrated above, usually they answer, that we are not writing a project for NASA, or anything like that so bug off. Interesting.
No comments:
Post a Comment