에디의 우당탕탕 코딩공장

[서버실습] 쓰레드와 동기화

by 인턴 에디

📌 커널 객체 제어를 위한 API

  커널 객체는 커널 모드에서만 접근이 가능

  -> 유저 모드의 프로세스들은 직접 해당 객체를 생성하거나 접근할 수 없다.

      커널 객체를 생성, 삭제, 접근하기 위해 커널에 요청 또는 접근을 가능하게 하는 표준 API들이 제공된다.

 

|커널 객체의 생성|    CreateXXX 형태로 되어있다.

HANDLE WINAPI CreateXXX
{
  _IN_opt PSECURITY_ATTRIBUTES pSecAttrs // 보안 속성 지정
  ...                                    // 객체별 자체 매개변수들
  _In_op_ PCTSTR pszObjectName           // 객체 이름 지정
};

- ID로 식별값을 대신하는 프로세스와 스레드는 리턴값을 DWORD 포인터 매개변수를 리턴값으로 사용한다.

- 프로세스간 공유가 되지 않는 커널 객체도 존대한다(ex_ IOCP)

 

 

|커널 객체 열기|

 이미 생성된 객체들을 공유하기 위해 OpenXXX 형태의 함수 제공.

HANDLE WINAPI OpenXXX
{
  _In_ DWORD dwDesiredAcecess,
  _In_ BOOL bInheritHandle,
  _In_ PCTSTR pszObjectName
};

위의 함수 호출이 성공할 때마다 해당 객체의 사용계수는 1씩 증가한다.

 

|커널 객체 닫기|

 커널 객체를 삭제하기 위해서는 커널 객체를 사용한 후 닫아줘야 한다.

BOOL WINAPT CloseHandle(_In_ HANDLE hObject);

- hObject:  Create 또는 Open을 통해 획득한 핸들값을 넘겨준다.

- CloseHandle 호출시마다 사용계수는 1씩 감소되고, 최종적으로 사용계수가 0이 되면 커널은 해당 객체를 메모리로부터 해제하게 된다.

- 생성된 커널 객체에 대하여 CloseHandle을 호출하지 않으면 결국엔 사용계수가 맞지 않아 해당 객체를 커널의 메모리로부터 삭제하지 못하게 됨으로써 메모리 누수가 발생한다.

 

📌 핸들과 핸들 테이블

typedef void* HANDLE;

CreateXXX를 보면, 리턴 타입은 HANDLE이며 위와 같이 재정의 되어있다.

핸들값은 객체의 포인터값 자체가 아니라 그 포인터와 연결된 식별값이다. 

 => 프로세스 A에서 생성한 커널 객체의 핸들값은 다른 프로세스에서는 의미가 없는 값이다.

출처: 윈도우시스템 프로그램을 구현하는 기술

블로그의 정보

에디의 우당탕탕 코딩 공장

인턴 에디

활동하기