블로그 이미지
대갈장군

calendar

1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31

Notice

2010. 3. 11. 00:29 프로그래밍/C
예전에 다른 글에서 Visual Studio의 Code Generation 옵션에 대해서 이야기 한 적이 있다. 

위 글에서는 간단하게 옵션에 대한 설명만 했지만 왜 싱글 스레드에서 멀티 스레드로 바뀌었는지에 대해서는 충분히 설명하지 못했다. 그래서 이 글을 추가로 작성한다.

C 언어는 멀티 스레드 개념이 생기기 이전의 언어이므로 멀티 스레드 환경에서 발생하는 자원 경쟁 상태 (Race Condition)을 염두해 두지 않았다. 즉, 여러개의 스레드가 하나의 전역 변수를 공유하여 서로 바꾸려고 할때 발생하는 경쟁 상태를 말하는데 이것의 대표적인 예로 C 언어의 errno 전역 변수이다.

이 전역 변수는 호출한 함수의 결과를 저장하는 전역 변수인데 싱글 스레드의 경우에는 아무런 문제가 없으나 멀티 스레드의 경우 임의의 함수 호출 후 다른 스레드가 또 다른 함수를 호출하여 그 결과를 errno에 저장해 버릴 수 있기 때문에 100% 신뢰할 수 있는 결과를 가지지 않는다. 

그래서 Microsoft사에서 내놓은 해결책이 멀티 스레드를 위한 새로운 런타임 라이브러리 사용이었다. 멀티 스레드를 위한 런타임 라이브러리는 멀티 스레드에서도 안정적인 C 함수들을 호출하므로 100% 신뢰할 수 있다. 


내가 늘 불만인 것은 Visual Studio는 이렇게 중요한 옵션에 대한 설명이 너무나 부족하다는 것이다. 초보 프로그래머는 절대로 "왜 이걸 써야 하지?" 라는 궁극적인 질문에 대답을 할 수 없다.

MSDN에 설명이 되어 있다고 하지만 그 마저도 C 언어를 안다는 가정하에 설명하고 있어서 읽다가 짜증만 난다. 쉽게 쉽게 풀어서 설명해 주면 안되겠니? 응?

아무튼, 배포를 위한 프로그램을 개발한다면 거의 /MD를 사용하면 된다. D가 의미하는 것이 다이나믹 링크이므로 프로그램을 설치할 컴퓨터에 Visual Studio C++ 런타임 라이브러리만 잘 설치되어 있으면 프로그램은 무리 없이 돌아갈 것이다.

하지만 한가지 더 중요한 것은 이렇게 /MD 설정으로만 모든 것이 해결되는 것은 아니며 스레드 생성시 반드시 _beginthreadex() 함수를 사용해라는 것인데, 이 함수는 스레드 생성 전에 스레드를 위한 독립 저장 공간을 생성하여 자원 경쟁을 예방한다. 이런 독립 공간을 스레드 지역 저장소라하며 원어로를 Thread Local Storage 라 부른다. 

그리고 생성을 저 함수로 했다면 스레드를 죽일때에는 _endthreadex()를 사용해야 한다. 

결론적으로,
  • C 언어는 싱글 스레드를 근간으로 작성되었으므로 멀티 스레드의 자원 경쟁 문제를 유발할 수 있다.
  • 그런 발생 가능한 문제 제거를 위해서는 멀티 스레드 런타임 라이브러리 옵션 (/MD)를 사용하면 된다.
  • 완벽한 문제 발생 제거를 위해서는 _beginthreadex()_endthreadex() 함수로 스레드를 생성하고 해제하라.


'프로그래밍 > C' 카테고리의 다른 글

C Language Constructors and Destructors with GCC  (0) 2015.02.12
C Standard Library  (0) 2010.09.25
호출 규약  (0) 2009.07.28
posted by 대갈장군