프로그래밍 노트

CreateSemaphore 본문

Win32 SDK 초보

CreateSemaphore

띠리 2007. 8. 30. 11:37
플렛폼 SDK

CreateSemaphore

유명한 혹은 무명한 세마포어 오브젝트를 만들거나 Open한다.

HANDLE CreateSemaphore(
  LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, // 시큐리티 기술자
  LONG lInitialCount,                          // 초기 카운트
  LONG lMaximumCount,                          // 최대 카운트
  LPCTSTR lpName                               // 오브젝트 이름
);
파라미터
lpSemaphoreAttributes

자식 프로세스가 얻은 핸들을 계승할 것인가를 결정한다.1개의 SECURITY_ATTRIBUTES 구조체에의 포인터를 지정한다.
NULL로 지정하면 자식 프로세스는 그 핸들을 계승할 수 없다.

Windows NT/2000:SECURITY_ATTRIBUTES 구조체의 lpSecurityDescriptor 멤버로 새로운 세마포어의 시큐리티 기술자를 설정한다. NULL로 지정하면 디폴트 값이 세마포에 할당된다.

lInitialCount

세마포어 오브젝트의 초기 카운트를 지정한다.
0 이상 lMaximumCount 이하의 값을 지정한다. 세마포어는 카운트가 0보다 큰 경우는 시그널 상태가 되고 카운트가 0일 경우는 비시그널 상태가 된다. 대기 함수(WaitForSingleObject 함수 등)을 사용해서 그 세마포어를 기다리고 있던 스레드를 풀어 주면 카운트가 하나 줄어든다.
ReleaseSemaphore를 사용하면 임의의 수만큼 값을 늘일 수 도 있다.
 
lMaximumCount

세마포어 오브젝트의 최대 값을 지정한다.
0보다 큰 값을 지정해야만 된다.
lpName
 
세마포어 오브젝트의 이름으로 NULL로 끝나는 문자열에 포인터를 지정한다. 이름의 최대 길이는 MAX_PATH의 길이이다. 이름을 비교할 때는 대문자와 소문자를 구별한다.

lpName 파라미터로 지정한 이름이 기존의 세마포어 오브젝트의 이름과 같을 경우,  이 함수를 실행하기위해서는 기존의 오브젝트에 대해서 SEMAPHORE_ALL_ACCESS 엑세스권이 필요한다. 이 경우, lInitialCount 파라미터와 lMaximumCount 파라미터는 오브젝트를 작성한 프로세스에 의해서 이미 설정되어 있기 때문에 무시한다. 또 lpSemaphoreAttributes 파라미터가 NULL이 아닐 경우, 자식 프로세스 핸들을 계승할 것인지를 지정하는 것은 유효하지만 시큐리티 기술자의 멤버는 무시된다.

lpName 파라미터로 NULL 을 지정하면 무명한 세마포어 오브젝트가 만들어진다.

lpName 파라미터로 지정한 이름이 기존의 이벤트, 뮤텍스, 대기 가능한 타이머, 잡, 파일 매핑 오브젝트중에 어떤 것과 같으면 이 함수는 실패하고 GetLastError함수는 ERROR_INVALID_HANDLE을 반환한다. 이것들의 오브젝트는 이름을 저장하는 공간을 공유하고 있기 때문이다.

Terminal Services:
글로벌로 이름을 저장하는 공간 또는 세션 이름을 저장하는 공간으로 오브젝트를 명시적으로 만들기 위해서는「Global\」혹은「Local\」의 prefix를 붙일 수 있다. 이름의 나머지 부분은 원기호(\)를 뺀 임의의 문자를 기술할 수 있다. 상세한 내용은 MSDN 라이브러리 「Kernel Object Name Spaces」를 참조

Windows 2000:Terminal Services가 동작하지 않는 Windows 2000 시스템에서는
「Global\」와「Local\」의 각 prefix는 무시된다.
이름의 나머지 부분은 원기호(\)를 뺀 임의의 문자를 기술할 수 있다.

Windows NT 4.0 이전과 Windows 95/98:이름의 원기호(\)를 뺀 임의의 문자를 기술할 수 있다.

반환값

함수가 성공하면 세마포오 오브젝트의 핸들을 돌려준다.
지정한 세마포어 오브젝트가 이미 존재하고 있는 경우도 이 오브젝트의 핸들을 돌려준다.
이 때 GetLastError함수는 ERROR_ALREADY_EXISTS를 돌려준다.

함수가 실패하면 NULL이 돌아오고 확장 에러 정보를 얻으려면 GetLastError함수를 사용한다.

해설

CreateSemaphore 함수가 돌려주는 핸들에는 새로운 세마포어 오브젝트에의 SEMAPHORE_ALL_ACCESS권이 할당되어져 세마포어 오브젝트의 핸들을 요구하는 임의의 함수로 사용할 수 있다.

호출하는 쪽 프로세스의 임의의 스레드는「wait functions」(대기함수)를 호출할 때에 세마포어 오브젝트의 핸들을 지정할 수 있다. 단일 오브젝트의 대기함수는 지정된 오브젝트가 시그널 상태가 되면 대기 상태에서 빠져나온다. 복수 오브젝트의 대기함수에 대해서는 지정된 오브젝트의 하나(혹은 모든것)이 시그널 상태가 되었을 때에 대기 상태에서 빠져나오도록 지시할 수 있다. 대기함수가 제어권을 돌려주면(대기 상태에서 빠져나오면) 대기중인 스레드가 풀려서 실행기 계속되어진다.

세마포어 오브젝트는 카운트가 0보다 큰 경우는 시그널 상태이고 카운트가 0의 경우는 비시그널 상태가 된다. 대기함수를 사용하여 세마포어를 기다리고 있던 스레드를 풀어주면 카운트가 하나 줄어든다. ReleaseSemaphore 함수를 사용하면 임의의 수만큼 늘일 수 있다. 카운트가 마이너스가 되거나 lMaximumCount 파라미터로 지정한 값보다 커지는 경우는 없다.

복수의 프로세스는 같은 세마포어 오브젝트의 핸들을 할당하여 프로세스간 동기의 목적으로 그 오브젝트를 사용할 수 있다. 다음과 같은 오브젝트 공유 메커니즘을 이용할 수 있다.

CreateSemaphore 함수의 lpSemaphoreAttributes 파라미터로 계승을 유효하게 해두면 CreateProcess함수가 만든 자식 프로세스는 세마포어 오브젝트 핸들을 계승할 수 있다.

•프로세스는 특정 이벤트 오브젝트의 핸들을 지정한 DuplicateHandle 함수를 호출함으로 핸들을 복사할 수 있다. 다른 프로세스는 그 핸들을 사용할 수 있다.

•프로세스는 OpenSemaphore 또는 CreateSemaphore 함수를 호출할 때 이벤트 오브젝트의 이름을 지정할 수 있다.

핸들을 닫을 때는 CloseHandle 함수를 사용한다. 프로세스가 종료될 때에 시스쳄은 그 프로세스가 가지고 있는 핸들을 자동적으로 닫는다. 세마포어 오브젝트에 대해서 하나나 또는 복수의 핸들이 열려있는 경우, 마지막 핸들이 닫힌 시점에서 그 세마포어 오브젝트가 파기되어진다.

대응정보

Windows NT/2000:Windows NT 3.1 이후
Windows 95/98:Windows 95 이후
해더:Winbase.h 안에 선언、Windows.h 을 include
임포트 라이브러리:Kernel32.lib 을 사용
Unicode:Windows NT/2000 は Unicode 판과 ANSI 판을 실장


http://msdn2.microsoft.com/en-us/library/ms682438.aspx

Comments