본문 바로가기

C/C++

Process 생성 및 종료

* 프로세스 생성
+ CreateProcess 함수를 사용하여 새로운 프로세스 생성
+ CreateProcess함수는 새로 생성된 프로세스가 완전히 초기화되기 전에 TRUE 반환
  - 운영체제의 로더가 새로운 프로세스가 필요로하는 dll을 로드하기 전에 TRUE를 반환하기 때문에,
    페어런트 프로세스는 차일드 프로세스에 어떤 초기화 문제가 발생했는지 알 수 없음

+ 새로운 프로세스를 만들면 시스템은 새로운 프로세스 커널 오브젝트와 스레드 커널 오브젝트를 생성
  - 커널 오브젝트가 새롭게 생성되면 사용 카운트(usage count) 값이 1로 초기화
  - CreateProcess 함수 반환 전, 프로세스 커널 오브젝트와 커널 오브젝트를 최대 접근 권한으로 한번 더 오픈
    PROCESS_INFORMATION 구조체 내의 hProcess와 hThread 멤버에 커널 오브젝트 핸들 값 할당
  - 즉, CreateProcess 내부에서 오브젝트를 다시 한번 열기 때문에 사용 카운트는 2가 됨
  - 그래서, 차일드 프로세스 뿐 아니라 페어런트 프로세스가 CloseHandle를 호출해야만 사용 카운트가 0이 되며,
    리소스 누수가 안생김
  - 대부분, 페어런트 프로세스가 차일드 프로세스 생성 후 바로 CloseHandle를 해준다
  - 주의 : 핸들을 삭제하는 것은 단순히 프로세스와 스레드의 통계적인 자료에 더이상 관심이 없다는 것을 알릴뿐,
    프로세스와 스레드는 자체적으로 종료될 때까지 계속 수행된다, 오해하지 말것!

 + 프로세스 커널 오브젝트가 생성되면 시스템은 이 오브젝트에 고유의 ID를 부여 (스레드도 동일)
  - 프로세스와 스레드 ID는 동일한 숫자 풀(pool)을 공유 -> 프로세스와 스레드의 ID 모두 다름
  - 윈도우 작업 관리자에서 'System Idle Process'를 ID '0'번 인것 처럼 보여주지만, 실제 존재 하지 않으며,
    가상의 프로세스가 있는 것처럼 보여줄 뿐,
    ~ System Idle Process의 스레드 개수는 머신 내의 CPU 개수와 동일하며, 
       실제 프로세스들이 사용하지 않는 CPU 사용율을 나타냄
  - 프로세스가 ID값을 얻고 프로세스가 종료되면 ID값을 반환하며, 다른 프로세스에게 그 ID 값 할당 가능
    ~ 그래서, 프로세스 ID를 사용하여 프로세스와 통신하는 것은 좋지 않다..!



* 프로세스 종료
프로세스 종료 방법 4가지
①  Return : 주 스레드의 진입점 함수 반환 (강추)
  - 이 방법만이 주 스레드의 리소스들이 적절히 해제되는 것을 보장
  - 소멸자 호출 / 메모리 해제 
  - 프로세스 커널 오브젝트의 사용 카운트 감소

② ExitProcess() : 프로세스 내의 어떤 스레드에서 ExitProcess() 호출  (비추)
  - ExitProcess 호출 후 프로세스 종료, 다른 스레드 또한 함께 종료
  - C/C++ 런타임이 관리하는 리소스에 대한 정리 작업을 수행하지 않음 (소멸자 호출 안돼)

③ TerminateProcess() : 다른 프로세스의 스레드가 TerminateProcess() 호출 (비추)
  - ExitProcess와 비슷
  - 자신의 프로세스 뿐 아니라 다른 프로세스까지 종료 가능
  - 운영체제를 통해 프로세스가 사용하던 모든 리소스는 완벽하게 정리
    (메모리 해제 / 커널 오브젝트 사용자 카운트 감소 등)

④ 프로세스 내의 모든 스레드가 각자 종료 (가끔 발생)

<출처 : 제프리 리처의 Windows via C/C++>