관리 메뉴

Kim's Programming

커널 오브젝트 그리고 Usage Count 본문

Programming/System Programming

커널 오브젝트 그리고 Usage Count

Programmer. 2016. 1. 1. 20:19

커널 오브젝트와 Usage Count


커널 오브젝트는 프로세스가 아닌 운영체제에 종속적이면 커널 오브젝트의 소멸시기는 운영체제에 의해서 결정됩니다. 일반적으로 CreateProcess함수를 통해서 커널 오브젝트를 생성한다고 생각되기도 하지만 CreateProcess함수는 커널오브젝트를 생성하는 함수가 아니라 운영체제에 프로세스 생성을 요청하는 함수이며 이 요청과정에서 운영체제가 관리를 편하게 하기위해 커널 오브젝트를 생성하게 됩니다.


CloseHandle 함수


어떤 프로세스가 생성되면 그 프로세스를 위한 커널 오브젝트가 생성됩니다. 이때 커널 오브젝트는 완전히 프로세스를 대표하게 됩니다. 하지만 그 반대는 성립하지 않습니다. 프로세스가 소멸된다해서 커널 오브젝트가 소멸되지는 않습니다. 그 이유는 커널 오브젝트의 소멸담당은 운영체제가 맡고 있기 떄문입니다. 운영체제가 커널 오브젝트의 소멸 시기를 결정짓는 기준에 대해서 알아보겠습니다. CloseHandle 활용 소스부터 보고가겠습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<tchar.h>
#include<Windows.h>
 
int _tmain(int argc, TCHAR *argv[])
{
    STARTUPINFO SI = { 0, };
    PROCESS_INFORMATION pi;
    SI.cb = sizeof(SI);
 
    TCHAR command[] = _T("child.exe");
    CreateProcess(NULL, command, NULL, NULL, TRUE, 0, NULL, NULL, &SI, &pi);
    CloseHandle(pi.hProcess);
 
    return 0;
}
cs

위 소스는 자식프로세스를 실행한 후에 종료하는 프로세스입니다.(자식프로세스는 전에 사용하던 것 그대로 사용하고있습니다.) 위 소스는 프로세스를 생성한 뒤에 CloseHandle함수로 프로세스 핸들을 전달합니다. 커널 오브젝트의 핸들은 PROCESS_INFORMATION의 객체 pi를 통해서 전달하게 됩니다.


다음은 CloseHandle함수의 구조입니다.

1
CloseHandle(HANDLE hObject);
cs

CloseHandle 함수는 핸들을 닫는(종료하는) 기능을 지니고 있습니다. 또는 핸들을 반환한다고도 합니다. 반환한다는 말은 Usage Count와 함께 있을때 의미가 분명해 지는데 바로 알아보겠습니다.



커널오브젝트와 Usage Count


자식 프로세스의 종료코드는 자식 프로세스의 커널 오브젝트에 저장됩니다. 하지만 자식프로세스가 소멸 후에 커널오브젝트도 소멸하게 되면 종료코드를 얻을 수 없습니다. 다시 말해 자식 프로세스의 종료코드를 부모프로세스가 얻을 수 없습니다. 하지만 그렇다고 아예 소멸을 안시킬 수도 없는데 언제 소멸을 할까요? 소멸의 시기는 그 프로세스의 커널오브젝트를 참조하는 대상이 하나도 없을 때 소멸시키는 것이 가장 이상적입니다. Windows는 다음과 같은 방식으로 커널 오브젝트를 소멸하게됩니다. Windows는 Usage Count라는 것을 통해서 참조대상의 갯수를 세개 되며 Usage Count가 0이 되는 순간에 해달 커널오브젝트를 소멸시키게 됩니다.


프로세스는 생성과 동시에 커널 오브젝트의 UC는 1이 됩니다. 만약 생성과 동시에 UC가 0일 경우에는 생성되자마자 파괴가 되기때문에 생성과 동시에 1이 됩니다. 또한 이상태에서 자식 프로세스를 만들게 되면 UC가 2가 되게 됩니다. 이렇게 된 후 CloseHandle을 사용하여 자식프로세스를 종료시키게 되면 UC는 1로 줄어들게 됩니다.


만약 바탕화면에 있는 아이콘을 실행한다면 UC는 얼마가 될까요? 1이 될 것 같지만 2가 됩니다. 왜냐하면 바탕화면을 구성하는 프로세스(explorer.exe)또한 프로세스이기 떄문입니다.