On multiple thread programming, we know that when multiple thread access share static variable will get race condition and have thread safe problem, no matter how many CPU Cores. Like this link can single processor environment prevent race condition?.
I will want to know how much time it takes to run multi-threaded and have race condition code under different numbers of CPU Cores (this is just self-study and I want to know, although this is meaningless)
I write following a .NET Console sample code, it create two threads.
thread1 will do int.MaxValue times in loop and will increase one for share static variable.
thread2 will do int.MaxValue times in loop and will reduced one for share static variable.
When I use Process.GetCurrentProcess().ProcessorAffinity
to set this process need multiple processor, because of race condition problems, the share static variable will not become 0 after the execution is completed, but an arbitrary value.
But I found when set this Process to only use one logical process by Process.GetCurrentProcess().ProcessorAffinity = (IntPtr)0b00010001;
or Process.GetCurrentProcess().ProcessorAffinity = (IntPtr)0b00010010;
or Process.GetCurrentProcess().ProcessorAffinity = (IntPtr)0b00010100;
In such an environment, has only one logical processor to execute this multi-threaded program, although a race condition occurs, the overall execution result seems to be thread safe. Because no matter how many times I execute, the share static variable, Counter, the final result is always 0.
I don't know why such a phenomenon occurs, Could anyone help explain :
Under the .NET CLR, it is specified that only a single CPU Core can be used, and after execution ends, it will have thread safety features, which means Counter This share static variable will always be 0
I recorded the entire test process, and the recorded video is at this URL
[Update]
I have use the .net disassembler of Visual Studio 2019 to check following C# code for IL Code:
for (int i = 0; i < int.MaxValue; i++)
{
Counter = Counter + 1;
}
The green area in the bottom of the disassembly code should generate a race condition, so that it will be executed under any number of CPU Cores, and the number of execution cycles will be enough, there will be problems.
class Program
{
public static long Counter = 0;
static void Main(string[] args)
{
Process.GetCurrentProcess().ProcessorAffinity =
(IntPtr)0b00010001;
Thread thread1 = new Thread(x =>
{
for (int i = 0; i < int.MaxValue; i++)
{
Counter = Counter + 1;
}
});
Thread thread2 = new Thread(x =>
{
for (int i = 0; i < int.MaxValue; i++)
{
Counter = Counter - 1;
}
});
thread1.Start(); thread2.Start();
thread1.Join(); thread2.Join();
Console.WriteLine($"Result={Counter}");
}
}