C#

[C#] 메모리 베리어 예제

소리쿤 2023. 3. 6. 01:03
	class Program
	{
		static int x = 0;
		static int y = 0;
		static int r1 = 0;
		static int r2 = 0;

		static void Main(string[] args)
		{
			int count = 0;

			while(true)
			{
				count++;

				x = y = r1 = r2 = 0;

				Task t1 = new Task(Thread1);
				Task t2 = new Task(Thread2);

				t1.Start();
				t2.Start();

				Task.WaitAll(t1, t2);

				if (r1 == 0 && r2 == 0)
					break;
			}

			Console.WriteLine($"{count}번만에 루프 탈출");
		}

		static void Thread1()
		{
			y = 1;

			Thread.MemoryBarrier(); 
			// Full Memory Barrier
			// 현재 스레드를 실행 중인 프로세서는 MemoryBarrier()에 대한 호출 이전의 메모리 액세스가 MemoryBarrier()에 대한 호출 이후의 메모리 액세스 뒤에 실행되는 방식으로 명령을 다시 정렬할 수 없습니다.

			r1 = x;
		}

		static void Thread2()
		{
			x = 1;

			Thread.MemoryBarrier();

			r2 = y;
		}
	}

 

https://learn.microsoft.com/ko-kr/dotnet/api/system.threading.thread.memorybarrier?view=net-7.0 

스레드 내에 Thread.MemoryBarrier 구문이 없는 경우,

 

y = 1; 

r1 = x;

 

위 두 구문이 종속성이 없다고 판단한 컴파일러가 두 구문의 순서를 바꿀 수 있다. ( 두 스레드 모두 동일 )

Thread.MemoryBarrier 를 명시하여 메모리 액세스 순서를 보장한다.

 

디스어셈블리로는 확인이 불가능했다.

뒤집힘을 확인할 수 있는 방법이 있을까?