티스토리 뷰
1. 프로세스
실행중인 프로그램을 말한다. 메모리에 적재되면 프로세스가 된다.
OS는 실행된 프로그램을 프로세스 단위로 관리한다. 프로세스가 종료될때 프로세스가 소유한 모든 자원은 OS에 의해 파괴된다.
프로세스 |
각각 4GB의 주소공간, 파일, 메모리, 스레등 등의 객체를 소유 |
스레드 |
윈도우, 메시지큐, 스택만 소유 |
윈도우 |
- |
프로세스는 실행중인 프로그램이지만 실제로 작업은 프로세스 내의 스레드가 담당한다.
프로세스는 단지 메모리상에 존재하기만 할 뿐이며 실행과 동시에 스레드(Primay Thread)를 하나 만들고 스레드를 호출함으로써 스레드에게 모든 작업을 맡긴다. 결국, 프로세스는 스레드를 담는 껍데기이며 실제 일하는 것은 스레드이다. CreateProcess()는 그러지 못함.
프로세스는 최소한 1개 이상의 스레드를 가진다. 프로세스와 동시에 만들어지는 스레드를 주 스레드(Primary Thread)라 하며 이외에 필요에 따라 여러 개의 스레드를 더 만들어 사용할 수도 있다. 하나의 프로세스가 복수 개의 스레드를 가질 수 있기 떄문에 멀티 스레드라고 하는 것이다.
1-1 프로세스 생성
UINT WinExec(LPCSTR lpCmdLine, UINT uCmdShow);
제일 간단한 함수로 프로세스가 처음으로 GetMessage()를 호출할때 리턴한다. 즉, 새 프로세스가 일련의 초기화 작업을 마무리하고 스스로 메시지를 처리할 수 있을때 리턴하므로 곧바로 FindWindow()로 생성도니 프로세스의 메인 윈도우를 찾을 수도 있고 SendMessage()로 메시지를 보낼 수도 있다.
lpCmdLine 인수로 실행하고자 하는 프로그램의 이름을 전달하되 완전 경로를 줄 수 이도 있다. 파일명만 주어지면 아래 순서대로 검색한다.
- 프로그램이 실행된 디렉토리
- 현재 디렉토리
- 시스템 디렉토리
- 윈도우즈 디렉토리
- PATH 환경변수가 지정하는 디렉토리들
uCmdShow은 실행 직후에 프로그램이 어떻게 보일지 지정, ShowWindow()의 nCmdShow인수와 동일한 값들을 사용할 수 이싿. SW_SHOWNORMAL, SW_SHOWMAXIMIZED, SW_SHOWMINIMIZED
BOOL CreateProcess(...);
인수가 복잡하나 자세한 제어가 가능하다.
프로세스를 생성한 후 곧바로 리턴하므로 이 함수가 리턴된 직후에는 초기화중이며 윈도우가 만들어져 있지 않아 FindWindow()로 찾지도 못하므로 이들 작업이 완료될때까지 기다려야 한다.
이때 DWORD WaitForIputIdle(HANDLE hProcess, DWORD dwMilliseconds); 를 호출하며 초기화와 윈도우가 만들어질때까지 기다린다. dwMilliseconds 는 기다릴 시간인데 얼마나 기다려야할지 모르므로 INFINITE 로 지정한다.
커널 객체는 여러 프로세스에서 동시에 참조할 수 있기 때문에 참조 카운트(Usage Count)가 유지되낟, 그래서 사용 후에는 반드시 CLoseHandle()로 핸들을 닫아야 하는데 만약 프로세스를 생성한 후 특별히 핸들을 사용하지 않는다면 프로세스 생성 후 핸들을 바로 닫는게 좋다.
1
2
3
4
5 |
if(CreateProcess(NULL, "NotePad.exe", NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)
{
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
} |
cs |
이 코드가 이상하게 보이겠지만 프로세스의 핸들과 프로세스 그 자체는 다르다는 점을 잘 생각해 보기 바란다. 핸들과 대상은 일체성이 있을 수도 있고 없을 수도 있는데 대부분의 핸들은 일체성이 있다. 윈도우나 펜, 동기화 객체 등은 핸들을 닫으면 대상체도 즉시 파괴되지만 프로세스, 스레드, 파일은 핸들과 대상의 일체성이 없어서 핸들과 대상이 별개이다. 그래서 핸들을 닫는다고 Notepad.exe가 종료된느 것은 아니다. 핸들을 닫는다는 것은 이 핸들로 더 이상 제어할 의사가 없다는 뜻일 뿐이다. 만약, 쓰지도 않을 핸들을 불필요하게 가지고 있으면 핸들의 사용 카운트가 증가하여 이 객체는 프로세스가 종료되어 강제 회수될 때까지 메모리를 낭비하게 될 것이다.