본문 바로가기
C#

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

by 소리쿤 2023. 3. 6.
	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 를 명시하여 메모리 액세스 순서를 보장한다.

 

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

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

'C#' 카테고리의 다른 글

[C#] Dispose 패턴  (0) 2023.03.23
[C#] Interlocked  (0) 2023.03.20
[C#] 캐시 Special Locality 테스트  (0) 2023.03.05
[C#] 컴파일러 최적화로 인한 데드락 예제  (0) 2023.03.03
[C#] Thread Join 예제  (0) 2023.02.27