공용 저장공간을 쓰레드에서 동시에 접근한다면?
namespace SeverCore
{
class Program
{
static bool _stop = false;
static void ThreadMain()
{
Console.WriteLine("쓰레드 시작!");
while (_stop == false)
{
//누군가가 stop 신호를 해주기를 기다린다
}
Console.WriteLine("쓰레드 종료!");
}
static void Main(string[] args)
{
Task t = new Task(ThreadMain);
t.Start();
Thread.Sleep(1000); //1초동안 대기
_stop = true;
Console.WriteLine("Stop 호출");
Console.WriteLine("종료 대기중");
t.Wait(); //Task가 끝나기를 기다림
Console.WriteLine("종료 성공");
}
}
}
위 코드를 실행하면 아무런 문제없이 잘 실행되고 있음을 알 수 있다.
즉 전역변수인 _stop을 동시에 접근할 수 있었다.

Visual Studio의 실행 옵션을 Debug에서 Release로 변경하면 온갖 최적화가 진행이 된다.

Release로 변경 후 아까와는 달리 제대로 실행이 되지 않고 있다.

어떤 최적화를 진행한 것일까?
while (_stop == false)
{
}
위 코드가 Release 모드에서는 아래와 같이 변경된 것이다.
if(_stop == false)
{
while(true)
{
}
}
그렇다면 최적화를 강제로 막는 방법은 무엇일까?
휘발성이라는 뜻을 가진 키워드 volatile를 이용한다.
언제 변할 지 모르니 최적화하지 말라고 전달하는 것이다.
volatile static bool _stop = false;
C#과 C++ 에서의 volatile 키워드 의미가 조금 다르니 주의할 것
더 좋은 방법이 있으나 이는 이후에 진행할 예정이니 volatile의 존재 정도만 알아둘 것!
namespace SeverCore
{
class Program
{
volatile static bool _stop = false;
static void ThreadMain()
{
Console.WriteLine("쓰레드 시작!");
while (_stop == false)
{
//누군가가 stop 신호를 해주기를 기다린다
}
Console.WriteLine("쓰레드 종료!");
}
static void Main(string[] args)
{
Task t = new Task(ThreadMain);
t.Start();
Thread.Sleep(1000); //1초동안 대기
_stop = true;
Console.WriteLine("Stop 호출");
Console.WriteLine("종료 대기중");
t.Wait(); //Task가 끝나기를 기다림
Console.WriteLine("종료 성공");
}
}
}