This is a C# version of this question: Is std::mutex sequentially consistent?
In short: if multiple threads take locks on different objects, are they guaranteed to see the same order of events within those different locks?
Here is the demonstration:
internal sealed class Test
{
private readonly object lockerA = new object();
private bool valueA;
private readonly object lockerB = new object();
private bool valueB;
public void RunTest()
{
var taskA = Task.Run(() =>
{
lock (lockerA)
valueA = true;
});
var taskB = Task.Run(() =>
{
lock (lockerB)
valueB = true;
});
var taskC = Task.Run(() =>
{
// Reads A, then B.
bool readA;
lock (lockerA)
readA = valueA;
bool readB;
lock (lockerB)
readB = valueB;
return (readA, readB);
});
var taskD = Task.Run(() =>
{
// Reads B, then A.
bool readB;
lock (lockerB)
readB = valueB;
bool readA;
lock (lockerA)
readA = valueA;
return (readA, readB);
});
Task.WaitAll(taskA, taskB, taskC, taskD);
if (taskC.Result == (readA:true, readB:false) && taskD.Result == (readA:false, readB:true))
{
// Can this happen?
Console.WriteLine("Ordering inconsistency!");
}
}
}
EDIT:
Fixed an error after Matthew Watson showed that the example fails even with sequential consistency.