◎스레드란?


 우리가 흔히 말하는 응용프로그램(프로세스)은 무엇을 실행할 수 없다. 프로세스는 단순히 스레드를 담는 상자라고 생각하면된다. 스레드는 항상 프로세스의 내부에서 실행이 되며 프로세스내에서 살아있게된다. 실제로 스레드는 프로세스 내부에서 코드를 실행하고 데이터를 조작한다. 하나의 프로세스는 다수의 스레드를 소유할 수 있으며 그 다수의 스레드들은 같은 주소공간을 공유한다. 그리고 이때 스레드들은 같은 코드를 실행하고, 같은 데이터를 조작한다. 동일한 프로세스내에 존재하는 스레드들은 커널 오브젝트를 공유할수있다. 그 이유는 핸들테이블이 각 스레드가 아니라 각 프로세스에 존재하기 때문이다.




◎스레드 사용하기


 프로세스의 주스레드는 CreateProcess를 호출해서 생성이된다. 우리가 알아볼 일은 주스레드가 다른 스레드를 만드는 방법이다.



                 HANDLE CreateThread(……) ; (함수에대한 설명은 MSDN을 찾아보세요)



이 함수가 호출이 될때 시스템은 스레드 커널 오브젝트를 생성한다. OS는 이 커널 오브젝트를 사용해서 스레드를 관리한다. 이 외에 시스템은 프로세스의 주소공간외에 스레드 스택이 사용하는 메모리를 할당한다. 새로운 스레드는 생성한 프로세스와 같은 프로세스에서 실행이 되며, 모든 프로세스 커널 오브젝트 핸들에 접근이 가능하고, 프로세스 내의 모든 메모리에 접근 및 같은 프로세스의 모든 다른 스레드의 스택에도 접근이 가능하다.


※ CreateThread는 윈도우 함수이다. 이와 같은 기능을 하는 C/C++ 런타임 라이브러리가 있다. 바로 _beginthreadex이다. CreateThread로 스레드를 생성후 스레드 종료시 tiddata데이터 블록이 제거되지 않는다. 그러므로 CreateThread보다는 _beginthreadex를 사용해라.


그리고 행여나 _beginthread, _endthread함수는 사용할 생각을 하지마라.;; _beginthread는 보안속성을 설정할수없으며, suspend도 할수없으며, 스레드 ID도 얻을수없다. _endthread()는 파라메터가 없고 종료코드는 항상 0 이며 내부에서 CloseHandle을 호출한다.(이 두함수 그냥 버려요 ^^)




◎ 스레드 종료


 스레드가 다음과 같은 경우에 종료된다.


  . 스레드 함수가 리턴할때 (강추 방법. Good!!)


  . ExitThread함수를 호출해서 스레드가 스스로 죽는것(안좋아요..ㅠㅠ)


  . 같은 프로세스 혹은 다른 프로세스 내의 스레드에서 TerminateThread함수 호출(안좋아요)


  . 스레드를 가지고 있는 프로세스를 종료. (이것도 안좋아요)



 ※ 스레드를 종료시킬때는 스레드 함수를 리턴시키는것이 가장 좋다.!!



스레드 함수가 리턴시 : 스레드 함수에서 모든 C++ 오브젝트는 소멸자에 의해서 제거되며, 운영체제는 스레드 스택으로부터 사용된 메모리를 반환한다, 시스템은 스레드 함수의 리턴값으로 스레드의 exit코드를 설정하며, 시스템은 스레드의 커널 오브젝트 사용횟수를 감소시킨다.



ExitThread 호출시 : 스레드가 사용하던 운영체제 자원을 모두 정리한다. 그러나 C/C++자원은 제거되지 않는다. << 아주 안좋다…;



TerminateThread 호출시 : 이 함수로 스레드를 종료시 시스템은 스레드가 소유하고있던 스레드의 스택을 소멸하지 않는다. 프로세스가 종료될때까지 기다린후 소멸시킨다. Dll은 스레드가 종료될때 Notify를 받는다(DllMain부분을 참조하세요), 그러나 TerminateThread 이 함수로 종료시 Dll은 Notify를 받지 못한다. 이런 상황은 Dll의 자원정리를 막는 현상을 야기한다. << 역시 안좋다.




◎ 스레드가 종료될때 일어나는 현상


 . 스레드 내의 모든 사용자 오브젝트 핸들이 소멸된다. 윈도우에서 대부분 오브젝트는 오브젝트를 생성하는 스레드를 가진 프로세스가 가지고있게된다. 그러나 윈도우와 훅(Hook)은 스레드가 갖게 된다. 스레드가 죽을때, 시스템은 자동으로 모든 윈도우를 없애고, 스레드가 생성하거나 초기화한 모든 훅은 제거한다. 다른 오브젝트는 그 오브젝트를 가지는 프로세스가 종료될때 제거된다.


 . 스레드의 exit코드는 ExitThread또는 TerminateThread가 전달될때 STILL_ACTIVE로부터 변한다.


 . 스레드 커널 오브젝트의 상태가 신호화(signal)된다.


 . 스레드가 프로세스에서 마지막 활동 스레드이면 시스템은 프로세스가 잘 종료될것이라 여긴다.


 . 스레드 커널 오브젝트의 사용횟수가 하나 감소한다.



Post to Twitter