커널 오브젝트와 핸들의 관계



프로세스가 생성될때 커널 오브젝트가 생성된다. 또한 그 프로세스의 핸들 테이블도 생성된다. 

핸들 테이블에 핸들 값이 있고 그 핸들값이 가리키는 대상 즉 커널 오브젝트가 저장된다. 

※핸들 테이블은 각 프로세스 영역에서만 의미를 지니기 때문에 가리키는대상이 같아도 핸들값이 다를 수 있다.


커널 오브젝트에는 그 커널오브젝트에 접근가능한 사용자의 수를 카운트하는 값이 존재한다. 만약 프로세스A가 생성된다면 그 값은 2가될겄이다. 하나는 자기자신일 것이도 다른 하나는 프로세스A를 실행시킨 그 무엇(마우스로 실행시키면 탐색기가 될수도있고 명령프롬프트가 될 수도 있다.)이 될 것이다.

자식 프로세스는 실행될때 부모 프로세스로 자신의 핸들값을 집어던진다.


프로세스가 소멸 될지라도 커널 오브젝트는 사라지지 않는다. 

다른 프로세스가 그 커널 프로세스를 참조 할 수도 있기때문이다.

하지만 이미 그 프로세스가 소멸 했는데 다른 프로세스가 참조한다해도 이미 할 수있는 일은 아무것도 없지않을까 ?

여기서 잠깐 C언어 프로그래밍을 보면 return 0,1,-1 또는 exit(-1),exit(1) 이런 식으로 종료되는 경우가 많다. 어차피 뭘 넣던 종료는 된다.

하지만 

뒤에 오는 값은 종료되는 프로세스의 부모프로세스에게 자신이 정상 종료인지 비정상 종료인지 알려주는 것이다.

부모 프로세스와 자식 프로세스가 완전 별도의 프로세스 일 수도 있지만 자식 프로세스의 결과에따라 부모 프로세스의 실행을 결정 할 수도 있기에 자식 프로세스가 정상적 종료인지 아닌지 궁금해 할 수도 있다.


프로세스가 종료될때 종료코드값를 리턴하는데 어디로 하느냐 바로 커널 오브젝트이다.  그래서 프로세스가 종료되어도 커널 오브젝트는 남아있는다.

그 커널 오브젝에 아무도 관심이 없어진 상태가 된야만 운영체제가 그 커널 오브젝트를 소멸 시킨다.



파일에 접근 할 때 ANSI 함수를 사용 하거나 시스템 함수를 사용 할 수 있다.

ANSI 함수를 사용하면 파일의 커널오브젝트가 생성되지 않는다고 알고있는 사람도 있다고하는데 ANSI 함수는 각 OS에 시스템 함수를 호출하는 방법으로 사용된다. 

즉 파일이 생성되면 반드시 커널 오브젝트는 생성된다.


프로세스가 자기 자신의 커널 오브젝트에 접근 할때는 핸들 테이블에 등록되어있는 값을 사용하는것이 아니라 자기자신을 의미하는 상수값을 반환받는다.



예제


#include <stdio.h>

#include <windows.h>

#include <tchar.h>


int _tmain(int argc, TCHAR* argv[])

{

STARTUPINFO si={0,};

PROCESS_INFORMATION pi;

si.cb=sizeof(si);


TCHAR command[]=_T("Operation2.exe");


CreateProcess(NULL,     // 프로세스 생성.

     command,

 NULL,

 NULL, 

 TRUE, 

 0, 

 NULL, 

 NULL, 

 &si, 

 &pi

);  //CreateProcess


while(1)

{

for(DWORD i=0; i<10000; i++)

for(DWORD i=0; i<10000; i++); //Busy Waiting!!

_fputts(_T("Operation1.exe \n"), stdout); 

timing+=1;

if(timing==2)

 SetPriorityClass(pi.hProcess,

 NORMAL_PRIORITY_CLASS);   //우선순위를 다시 낮춘다.


}


return 0;

}


--------------------------------------------------------------------------------

Operation2.exe


#include <stdio.h>

#include <windows.h>

#include <tchar.h>


int _tmain(int argc, TCHAR* argv[])

{

SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS);


while(1)

{

for(DWORD i=0; i<10000; i++)

for(DWORD i=0; i<10000; i++); //Busy Waiting!!


_fputts(_T("Operation2.exe \n"), stdout); 

}


return 0;

}


저번 예제와 거의 같다. 달라진 점은 프로세스를 실행시키면 자식프로세스인 operation.exe는 자신의 우선순위를 높인다. 그후에 부모프로세스가 우선순위를 다시 일반적 우선순위로 바꾼다. 

프로세스를 실행시킬때 PROCESS_INFORMATION pi; 구조체를 전달해주는데 

pi 구조체의 pi.hProcess를 통해 해당 프로세스를 통해 접근하게 된다.





+ Recent posts