ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Volatile 변수란?
    Windows 프로그래밍 2019. 1. 7. 16:35

    이름부터 신기한 볼라틸 변수에 대해 알아보자.

    결론부터 말하자면 볼라틸로 선언한 변수는 사용할 때 마다 메모리에 접근해 해당 변수의 값을 확인한다.

    그럼 이제 이걸 왜 쓰는지 이유를 알아보도록 하자.

     

    아래와 같은 코드가 있다. 

    쓰레드를 실행하는 함수 하나와 check값이 FALSE 이면 계에에에속 도는 while문이 Main에 있다.

    Main에서 실행한 쓰레드에서는 check 값을 TRUE로 바꿔준다.

    BOOL check = FALSE; int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE, LPSTR lpCmdLine, int nCmdShow){ DWORD dwThreadId; CreateThread(NULL, 0, ThreadFunc, NULL, 0, &dwThreadId); while(!check){ NULL; } return 0; } DWORD WINAPI ThreadFunc (LPVOID) { check = TRUE; return 0; }

    그냥 결과를 예측해보자. 쓰레드에서 check값을 TRUE로 바꿔줄 것이고 당연히 while문은 동작하지 않을 것이다.

    하지만! 이걸 Release 모드로 컴파일하고 결과를 보면? 아마 프로그램이 끝나지 않을 것이다.

     

    왜 이런 현상이 일어나는 걸까? 문제는 코드 최적화에 있다.

    Release 모드로 컴파일하게 되면 컴파일러는 check 값이 쓰레드에서 변경되는 줄 모르고 최초의 check 값으로 판단하게 된다. 즉,  쓰레드에서 바뀐 check 값은 신경도 쓰지 않고 그냥

     

    쓰레드 : "휴... check값 TRUE로 바꿨다."

    while문 : "check가 FALSE네? 어라? FALSE면 무한루프네? 돌려~~"

    쓰레드 : "어 잠깐만... 나 바꿨는데?"

    while문 : "에벱ㅂ베ㅔ베ㅔㅂ 안들려~~~~!"

     

    이렇게 되는 것이다...

    사실 컴파일러를 욕할 순 없는게 누가 봐도 while문 돌리는 것 보단 이렇게 값을 예측하는게 실행시간을 단축시킬 수 있다.

     

    어쨌든 이런 문제를 해결할 수 있는게 바로 volatile 변수이다.

    check 변수를

    volatile BOOL check = FALSE;

    요렇게 선언하면 while문에서 check를 검사할 때마다 check 변수가 담겨있는 메모리에 접근해 값을 확인하기 때문에 위와 같은 문제를 해결할 수 있다.

     

    따라서 오늘의 결론은 쓰레드에서 사용하는 전역변수라면 꼭 volatile로 선언하자~!!

    댓글

Designed by Tistory.