블로그 이미지
대갈장군

calendar

1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30

Notice

2012. 12. 13. 04:43 프로그래밍

http://msdn.microsoft.com/en-us/library/windows/desktop/ms724485(v=vs.85).aspx


Kernel Object (줄여서 KO) 핸들은 프로세스 한정적이다. 즉, 각각의 프로세스마다 고유하다는 말인데, 그말인 즉슨, 임의의 프로세스는 하나의 커널 오브젝트 핸들을 얻기 위해서는 반드시 오브젝트를 생성하거나 혹은 이미 존재하고 있는 오브젝트를 열어야 한다는 말이다. 하나의 프로세스 당 만들수 있는 최대의 커널 핸들의 갯수는 2의 24승이다. 뭐, 무제한이라고 보면 되겠네. 그러나, 핸들들은 Paged Pool에 저장되므로 결론적으로 사용가능한 메모리에 따라 생성할 수 있는 핸들의 갯수는 제한된다. 32 비트 윈도우즈 시스템의 경우 생성할 수 있는 핸들의 갯수는 2의 24승 보다 훠어얼씬 적다. 


프로세스는 오브젝트의 이름과 접근 권한을 가지고 있다면 이미 존재하고 있는 커널 오브젝트에 새로운 핸들을 할당하는 것이 가능하다. 심지어 그 커널 오브젝트가 다른 프로세스에 의해 만들어 졌다고 해도 가능하다. 커널 오브젝트 핸들은 그 자체에 접근 권한을 설정하는 속성을 가지고 있어서 접근을 허용 또는 차단을 할 수 있다. 보안 속성이라고도 한다. 각각의 커널 오브젝트는 고유의 접근 권한을 가지는데 예를 들자면 이벤트 핸들 같은 경우에는 'Set' 혹은 'Wait'를 가질 수 있고 파일 핸들 같은 경우에는 'Read' 혹은 'Write' 같은 접근 권한을 가질 수 있다.


아래의 그림을 보면 어플리케이션이 하나의 이벤트 오브젝트를 생성하는데 CreateEvent 함수가 이벤트 오브젝트를 생성하고 오브젝트 핸들을 리턴하고 있다.



Application creating an event object


이벤트 오브젝트가 생성된 후, 어플리케이션은 이벤트 핸들을 이용해 이벤트를 Set 혹은 Wait 시킬 수 있다. 이 핸들은 어플리케이션이 핸들을 닫거나 어플리케이션 자체가 종료될 때 까지 유효하다. 


대부분의 커널 오브젝트들은 하나의 오브젝트를 위해 다수의 핸들을 제공할 수 있다. 예를 들자면 아래 그림처럼 CreateEvent로 핸들을 하나 생성한 후 다시 OpenEvent로 같은 이벤트 오브젝트를 위한 핸들을 생성할 수 있다는 말이다. 


Application creating an event object with multiple handles


이런 방법으로 어플리케이션은 여러개의 핸들에게 다른 속성의 접근 권한을 부여 할 수 있다. 예를 들자면 Handle 1은 Set과 Wait 모두를 할 수 있게 접근 권한을 주고 Handle 2는 오로지 Wait만 가능하도록 설정 가능 하다는 말이다.


만약 다른 프로세스가 어떤 이벤트의 이름과 그 이벤트로의 접근 권한을 가지고 있다면 그 프로세스는 자신만의 이벤트 오브젝트 핸들을 OpenEvent 함수를 이용해서 생성 할 수 있다. DuplicateHandle을 이용하면 같은 프로세스 내에서 핸들을 복사 하여 생성할 수도 있고 다른 프로세스로 복사해서 전달 할 수도 있다.


하나의 오브젝트는 최소한 한개의 오브젝트 핸들이 존재하는 한 메모리에 계속 상주한다. 아래 그림처럼 어플리케이션이 CloseHandle함수를 사용해서 모든 오브젝트 핸들을 닫게 되면 비로서 오브젝트는 메모리상에서 사라지게 된다. 

Application closing event object handles to remove object from memory


흠, 이것은 마치 COM 오브젝트가 스스로를 관리하는 카운터를 가지고 있다가 0이되면 자폭하는 것과 같은 원리다. 제법 능동화된 메모리 관리 기법이지만 제대로 해제하지 않으면 어플리케이션이 종료되기 전까지는 절대 사라지지 않는 메모리 누수를 가지는 위험성이 존재한다.


윈도우 시스템은 다른 커널 오브젝트와는 조금 다른 방식으로 파일 오브젝트를 관리한다. 파일 오브젝트는 파일 포인터를 가지고 있다. 이 포인터는 파일내부의 읽혀질 혹은 쓰여질 다음 바이트의 위치를 가리키는 포인터이다.  어플리케이션이 새로운 파일 핸들을 생성할 때 시스템은 새로운 파일 오브젝트를 생성한다. 그러므로 하나 이상의 파일 오브젝트는 디스크 상의 한개의 파일을 가리킬 수 있는데 다음 그림과 같다. 


Multiple file objects referring to a file on disk


Duplication 이나 Inheritance (상속)을 통하면 한개 이상의 파일핸들이 같은 파일 오브젝트를 가리킬 수 있다. 다음 그림처럼.



Two file handles refer to same file object



사실 위 두개의 그림의 차이가 뭔지 잘 느낌이 안온다. 아마도 같은 파일 오브젝트를 공유하는 경우에 좀 더 자원경쟁에 안정적인 구현이 가능하다는 점이 다를까? 여러개의 다른 파일 오브젝트가 동시 다발적으로 한개의 파일에 접근하는 경우를 예방할 수 있다는 것이 장점일까? 


다음 도표를 보면 다양한 커널 오브젝트들이 나열되어 있다. 보면 생성 함수와 파괴 함수가 나열되어 있다. 시스템은 커널 오브젝트를 가리키는 최후의 핸들이 닫히면 자동으로 메모리에서 커널 오브젝트를 날려 버린다.


내가 내 생각대로 정리하자면, 커널 오브젝트는 보안 속성 (접근 제한)과 상태를 가지고 시스템에 의해 관리를 받는 일종의 구조체이다. 이런 커널 오브젝트가 중요한 이유는 시스템의 모든 중요 업무는 이런 커널 오브젝트를 통해서 이루어지고 있기 때문에다. 왜냐면 시스템이 이런 커널 오브젝트를 체계적으로 관리하여 사용자의 삽질을 막고 동시에 안전성을 높인다. 하지만 나에게 지금 커널 오브젝트가 중요한 이유는 바로 '상태' 때문이다. 커널 오브젝트가 상태를 가지기 때문에 스레드 간의 동기화에 요긴하게 쓰인다. 다름 글에서 어떻게 사용하는지 써보겠다.


Kernel objectCreator functionDestroyer function
Access tokenCreateRestrictedToken,DuplicateTokenDuplicateTokenEx,OpenProcessToken,OpenThreadTokenCloseHandle
Change notificationFindFirstChangeNotificationFindCloseChangeNotification
Communications deviceCreateFileCloseHandle
Console inputCreateFile, with CONIN$CloseHandle
Console screen bufferCreateFile, with CONOUT$CloseHandle
DesktopGetThreadDesktopApplications cannot delete this object.
EventCreateEventCreateEventEx,OpenEventCloseHandle
Event logOpenEventLog,RegisterEventSource,OpenBackupEventLogCloseEventLog
FileCreateFileCloseHandleDeleteFile
File mappingCreateFileMapping,OpenFileMappingCloseHandle
Find fileFindFirstFileFindClose
HeapHeapCreateHeapDestroy
I/O completion portCreateIoCompletionPortCloseHandle
JobCreateJobObjectCloseHandle
MailslotCreateMailslotCloseHandle
Memory resource notificationCreateMemoryResourceNotificationCloseHandle
ModuleLoadLibraryGetModuleHandleFreeLibrary
MutexCreateMutexCreateMutexEx,OpenMutexCloseHandle
PipeCreateNamedPipeCreatePipeCloseHandle,DisconnectNamedPipe
ProcessCreateProcessOpenProcess,GetCurrentProcessCloseHandle,TerminateProcess
SemaphoreCreateSemaphore,CreateSemaphoreEx,OpenSemaphoreCloseHandle
Socketsocketacceptclosesocket
ThreadCreateThread,CreateRemoteThread,GetCurrentThreadCloseHandle,TerminateThread
TimerCreateWaitableTimer,CreateWaitableTimerEx,OpenWaitableTimerCloseHandle
Update resourceBeginUpdateResourceEndUpdateResource
Window stationGetProcessWindowStationApplications cannot delete this object.

 







posted by 대갈장군