커널에 의해 관리되는 리소스 정보를 담고 있는 데이터 블록. 구조체 변수.
즉 윈도우즈에 의해 생성되는 모든 리소스는 커널 오브젝트 생성을 동반한다.
커널(Kernel)
운영체제의 핵심이 되는 부분.
리소스: 운영체제에 의해 생성 및 소멸되는 것.
ex) 배열을 선언했을 경우, 배열은 프로그래머에 의해 관리되는 리소스 정보를 담고 있는 데이터 블록.
ex) 파일 - 운영체제 + 프로그래머에 의해 관리되는 리소스. 파일 자체는 읽고 쓰는 권한을 가지고 있지 않고, 운영체제가 이를 관리한다. 즉, 프로그래머가 파일 관련 함수를 사용해 파일 할당을 요청하면 운영체제는 요구에 맞게 파일을 생성. 그리고 합법적인 접근을 하지 않았을 경우에도 운영체제가 이를 막는다.

리소스마다 관리되어야 하는 데이터가 다르기 때문에 각 커널 오브젝트는 다르게 디자인되어 있다.
ex) 프로세스 생성 - 해당 프로세스를 관리하기 위한 커널 오브젝트가 생성됨
ex) 파일 생성 - 해당 파일을 관리하기 위한 커널 오브젝트가 생성됨

핸들 (Handle)
커널 오브젝트를 간접적으로 관리하기 위한 고유 번호.
프로세스 생성 - 프로세스의 커널 오브젝트 생성 - 핸들 생성
커널 오브젝트는 우선 순위 정보를 가지고 있음.
커널 오브젝트의 경우 매우 중요하기 때문에 우선 순위 정보는 OS에 의해 관리되고, 프로그래머가 직접적으로 접근할 수 없다.
따라서 프로그래머가 해당 우선 순위를 변경하고 싶을 경우, 윈도우즈에서 제공되는 함수를 이용해 간접적으로 접근해야 한다.
우선 순위를 변경하기 위해서는 어떤 프로세스의 우선 순위를 바꿀지 정보를 넘겨야 하는데, 이 때 핸들이 사용된다. 핸들을 얻는 방법은 리소스마다 다르다.

#include <stdio.h>
#include <tchar.h>
#include <windows.h>
int _tmain(int argc, TCHAR* argv[])
{
STARTUPINFO si = {0,};
PROCESS_INFOMATION pi;
si.cb = sizeof(si);
TCHAR command[] = _T("Operation2.exe");
bool bState = CreateProcess(
NULL, command, NULL, NULL,
TRUE, 0, NULL, NULL, &si, &pi
);
if (false != bState)
{
while (true)
{
for (DWORD i = 0; i < 10000; ++i)
{
for (DWORD i = 0; i < 10000; ++i)
{
// Busy Waiting!
}
}
_fputts(_T("Operation1.exe\n"), stdout);
}
}
return 0;
}
해당 모든 과정은 운영체제에서 일어나는 일.
프로세스 A가 B를 생성했을 경우, B는 파일을 생성하는 상황.
1) 프로세스의 A의 생성과 함꼐, 프로세스 A의 커널 오브젝트와 + 핸들 테이블이 생성됨
해당 핸들 테이블은 프로세스 A가 접근할 수 있다.
핸들 테이블에는 커널 오브젝트의 핸들 값이 저장되어 있고, 이를 key값으로 매핑되는 자신의 커널 오브젝트를 찾을 수 있다. ex) 핸들 값 = 3
Usage Count: 프로세스 A에 접근할 수 있는 사용자.2) 프로세스 A를 주체로 프로세스 B를 생성
프로세스 B의 핸들 값은 핸들 테이블에 등록되고, 이는 프로세스 B의 커널 오브젝트를 가리킴. ex) 핸들 값 = 3

UC를 두는 이유
프로세스 B가 사라질 경우, B의 핸들 테이블도 사라진다. 그러나 프로세스 B의 커널 오브젝트에 아직 관심을 가지고 있는 프로세스가 있을 수 있기 때문에(여기서는 프로세스 A) 커널 오브젝트까지 바로 사라지는 것은 아니다. 이 경우 커널 오브젝트의 UC는 1이 깎이고, UC가 0일 때 커널 오브젝트는 종료된다. 이 시점은 운영체제에 의해 결정된다.
그러나 파일의 경우 UC = 0이 되었다고 물리적으로 사라지는 것은 아니다.
프로세스 자신의 핸들 정보는 핸들 테이블에 등록되지 않는다. 그러면 프로세스는 자신의 커널 오브젝트에 어떻게 접근하는가.
GetCurrentProcess()함수를 호출하면 임의의 핸들 값을 반환한다. 해당 값은 어떤 프로세스가 호출하던 언제나 같은 고유 값이다. 프로세스 자기 자신을 의미하는 상수 값. 이 값을 통해 자기 자신의 커널 오브젝트에게 접근할 수 있다.
커널 오브젝트를 생성한 주체가 종료되었는데도 불구하고 커널 오브젝트를 남겨둬야 하는 이유
부모 프로세스와 자식 프로세스는 기본적으로 서로 독립적이지만, 부모 프로세스가 자식 프로세스의 실행 상태에 따라 자신의 상태를 결정지을 수도 있다.
프로세스 B가 종료될 경우, 종료 코드에서 반환한 값이 B의 커널 오브젝트에 저장된다. 따라서 프로세스 B의 종료와 함께 커널 오브젝트가 소멸된다면 해당 반환 값을 부모 프로세스 A가 확인할 수 없기 때문에 자식 프로세스가 정상적으로 종료되었는지 알 수 없게 된다.
파일에 접근하기 위한 방법
1) ANSI 표준 함수
내부적으로 윈도우즈의 System 함수를 호출하는 구조.
2) 윈도우즈에서 제공하는 System 함수 이용
CloseHandle() 함수
커널 오브젝트의 UC를 1 줄이고, 핸들 테이블에 등록되어 있는 핸들 정보를 삭제하는 함수.
자식 프로세스 B의 커널 오브젝트의 UC가 1일 경우, 이는 부모 프로세스 A가 종료되어야 비로소 UC가 0이 되고, 종료된다. 그러나 프로세스 B의 커널 오브젝트가 더 이상 필요가 없는데도 남아 있을 경우 이는 리소스 낭비이다. 따라서 어떤 커널 오브젝트가 더 이상 필요없을 경우 CloseHandle()함수를 통해 이를 명시해줘야 한다.