1. 함수의 원형
HANDLE WINAPI CreateEvent(LPSECURITY_ATTRIBUTES lpEventAttributes,
BOOL bManualReset, BOOL bInitialState, LPCTSTR lpName);
BOOL bManualReset, BOOL bInitialState, LPCTSTR lpName);
2. 함수의 기능
이름이 정해진 또는 이름이 없는 이벤트 객체를 열거나 생성하는 함수이다. 이 객체에
접근할수 있는 경우를 명시하고 싶다면 CreateEventEx 함수를 사용해야 한다.
3. 함수의 매개변수에 대한 설명
3.1 lpEventAttributes
SECURITY_ATTRIBUTES 구조체로 선언된 변수의 주소를 명시한다. 이 매개변수에 NULL을 명시하면
생성된 이벤트 핸들은 자식 프로세스에 상속되지 않는다. SECURITY_ATTRIBUTES 구조체의 항목인
lpSecurityDescript-xor에는 새로운 이벤트의 보안 기술자(security descript-xor)에 대하여 명시하도록 되어있다.
만약, 이 매개변수에 NULL을 사용하여 보안 기술자에 대한 명시를 하지 않은 경우에는, 새로 생성될
이벤트 객체에 일반적인 보안 기술자가 명시된걸로 간주한다. 일반적인 보안 기술자의
ACL(Access Control List)은 현재 로그인되어 있는 사용자의 로그인정보에 있는 ACL을 이용하거나
이벤트 객체를 생성한 프로세스의 ACL을 가져와 사용한다.
3.1 lpEventAttributes
SECURITY_ATTRIBUTES 구조체로 선언된 변수의 주소를 명시한다. 이 매개변수에 NULL을 명시하면
생성된 이벤트 핸들은 자식 프로세스에 상속되지 않는다. SECURITY_ATTRIBUTES 구조체의 항목인
lpSecurityDescript-xor에는 새로운 이벤트의 보안 기술자(security descript-xor)에 대하여 명시하도록 되어있다.
만약, 이 매개변수에 NULL을 사용하여 보안 기술자에 대한 명시를 하지 않은 경우에는, 새로 생성될
이벤트 객체에 일반적인 보안 기술자가 명시된걸로 간주한다. 일반적인 보안 기술자의
ACL(Access Control List)은 현재 로그인되어 있는 사용자의 로그인정보에 있는 ACL을 이용하거나
이벤트 객체를 생성한 프로세스의 ACL을 가져와 사용한다.
ACL에 대한 좀더 자세한 내용은 아래의 항목을 참고하시기 바랍니다.
http://www.tipssoft.com/bulletin/tb.php/FAQ/15
http://www.tipssoft.com/bulletin/tb.php/FAQ/15
3.2 bManualReset
이 매개변수에 TRUE를 명시하면 발생된 이벤트 정보가 계속 유지되는 이벤트 객체를 생성한다.
즉, 이벤트 객체에 SetEvent 함수를 이용하여 이벤트를 설정하면 ResetEvent 함수를 호출하여
해제하기 전까지 계속 이벤트가 발생한 상태로 유지된다.
이 매개변수에 TRUE를 명시하면 발생된 이벤트 정보가 계속 유지되는 이벤트 객체를 생성한다.
즉, 이벤트 객체에 SetEvent 함수를 이용하여 이벤트를 설정하면 ResetEvent 함수를 호출하여
해제하기 전까지 계속 이벤트가 발생한 상태로 유지된다.
반대로 이 매개변수에 FALSE를 명시하면 자동으로 이벤트가 해제되는 이벤트 객체를 생성한다.
즉, 이벤트를 기다리는 스레드가 이벤트가 발생한 상황을 체크하게 되면 자동으로 이벤트
정보가 해제된다. 따라서 별도의 ResetEvent 함수를 호출할 필요가 없다.
3.3 bInitialState
이 매개변수가 TRUE라면 이벤트 객체는 이벤트가 발생한 상태로 생성되며 FALSE이면 이벤트가
발생하지 않은 상태로 생성된다.
3.4 lpName
이 매개변수에는 이벤트 객체에 사용할 이름을 명시한다. 여기에 사용되는 이름의 길이는
MAX_PATH까지로 제한되며 대소문자를 구별(Tips, tips, tipS는 서로 다른걸로 간주)한다.
만약, 명시한 이름이 이미 생성된 다른 이벤트 객체에 사용되고 있다면 이미 생성된 객체와
이벤트 발생정보를 공유하게 된다. 따라서 먼저 만들어진 이벤트 객체의 정보가 우선시
되기 때문에 현재 사용한 bManualReset(3.2), bInitialState(3.3)에 명시한 정보는 무시된다.
그리고 lpEventAttributes(3.1)에 NULL이 아닌 보안정보가 명시된 경우, 먼저 생성된
이벤트 객체의 보안 기술자에 의해서 사용되어질것인지 결정되며 사용가능하다고
판단되더라도 해당 구조체의 세부항목인 보안기술자 항목에 명시된 정보는 무시된다.
따라서 고유한 이벤트 객체를 생성하려면 이벤트 이름을 명시할때 주의해야 한다.
즉, 이벤트를 기다리는 스레드가 이벤트가 발생한 상황을 체크하게 되면 자동으로 이벤트
정보가 해제된다. 따라서 별도의 ResetEvent 함수를 호출할 필요가 없다.
3.3 bInitialState
이 매개변수가 TRUE라면 이벤트 객체는 이벤트가 발생한 상태로 생성되며 FALSE이면 이벤트가
발생하지 않은 상태로 생성된다.
3.4 lpName
이 매개변수에는 이벤트 객체에 사용할 이름을 명시한다. 여기에 사용되는 이름의 길이는
MAX_PATH까지로 제한되며 대소문자를 구별(Tips, tips, tipS는 서로 다른걸로 간주)한다.
만약, 명시한 이름이 이미 생성된 다른 이벤트 객체에 사용되고 있다면 이미 생성된 객체와
이벤트 발생정보를 공유하게 된다. 따라서 먼저 만들어진 이벤트 객체의 정보가 우선시
되기 때문에 현재 사용한 bManualReset(3.2), bInitialState(3.3)에 명시한 정보는 무시된다.
그리고 lpEventAttributes(3.1)에 NULL이 아닌 보안정보가 명시된 경우, 먼저 생성된
이벤트 객체의 보안 기술자에 의해서 사용되어질것인지 결정되며 사용가능하다고
판단되더라도 해당 구조체의 세부항목인 보안기술자 항목에 명시된 정보는 무시된다.
따라서 고유한 이벤트 객체를 생성하려면 이벤트 이름을 명시할때 주의해야 한다.
만약, 이 매개변수에 명시한 이름이 이미 생성된 Semaphore, Mutex, Waitable timer, Job
또는 File-mapping 객체에 사용되고 있다면 이 함수는 실패할것이고 정확한 오류체크를
위해 GetLastError 함수를 호출하면 ERROR_INVALID_HANDLE 값이 반환될 것이다.
즉, 하나의 객체는 다른 형식의 객체와 이름을 공유할수 없고 동일한 형식의 객체에서만
공유여부가 결정되어진다.
또는 File-mapping 객체에 사용되고 있다면 이 함수는 실패할것이고 정확한 오류체크를
위해 GetLastError 함수를 호출하면 ERROR_INVALID_HANDLE 값이 반환될 것이다.
즉, 하나의 객체는 다른 형식의 객체와 이름을 공유할수 없고 동일한 형식의 객체에서만
공유여부가 결정되어진다.
이 매개변수에 NULL을 명시하면 이름없는 이벤트 객체를 생성한다.
추가적으로 객체의 이름을 명시할때, 시스템 전역적으로 객체의 이름을 공유하고 싶다면
사용하고자 하는 이름앞에 "Global\"이라는 접두어를 사용하고 현재 세션공간에서만
사용하고 싶을때에는 "Local\"이라는 접두어를 사용할수 있다.
추가적으로 객체의 이름을 명시할때, 시스템 전역적으로 객체의 이름을 공유하고 싶다면
사용하고자 하는 이름앞에 "Global\"이라는 접두어를 사용하고 현재 세션공간에서만
사용하고 싶을때에는 "Local\"이라는 접두어를 사용할수 있다.
"Global" 또는 "Local" 이라는 접두어를 사용할수 있는 커널 객체에 대해서 좀더 자세한
내용을 원하신다면 아래 내용을 참고하시기 바랍니다.
내용을 원하신다면 아래 내용을 참고하시기 바랍니다.
( Kernal Objcet Namespace ) - http://www.tipssoft.com/bulletin/tb.php/FAQ/17
그리고 사적인 이름공간에도 이벤트 객체를 생성할수 있는데 이방법에 대해서 좀더
자세한 내용을 원하신다면 아래 내용을 참고하시기 바랍니다.
[ Object Namespaces ] - http://www.tipssoft.com/bulletin/tb.php/FAQ/18
자세한 내용을 원하신다면 아래 내용을 참고하시기 바랍니다.
[ Object Namespaces ] - http://www.tipssoft.com/bulletin/tb.php/FAQ/18
4. 함수의 반환값
이 함수가 성공적으로 수행을 완료했다면 생성된 이벤트 객체의 핸들이 반환될 것이다. 만약,
lpName에 사용한 이름과 동일한 이름으로 생성된 이벤트 객체가 이미 생성되어 있다면
해당 객체의 핸들이 반환될것이다. 이때, GetLastError 함수를 호출해보면
ERROR_ALREADY_EXISTS가 반환될 것이다. 따라서 다른 프로세스와 이벤트 객체가
공유되는것을 원치 않는다면 CreateEvent 함수가 정상적인 이벤트 핸들값을 반환하더라도
GetLastError 함수를 호출하여 ERROR_ALREADY_EXISTS 값이 반환되는지를 체크하는것도
좋은 방법일 것이다.
만약 함수가 실패한다면 NULL값이 반환될 것이고, GetLastError 함수를 호출해서 좀더 자세한
오류 상황을 확인할 수 있다.
오류 상황을 확인할 수 있다.
5. 함수 사용시 주의사항
CreateEvent 함수로 생성된 이벤트 객체의 핸들은 EVENT_ALL_ACCESS 권한을 가지고 있다. 따라서
이 핸들은 이벤트 객체의 핸들을 요구하는 대부분의 함수에 사용할 수 있다.
( CreateEvent 함수 호출시에 lpEventAttributes를 이용하여 보안을 명시했다면 해당 보안사항에
만족하는 경우에만 이 핸들을 정상적으로 사용할 수 있다. )
이 핸들은 이벤트 객체의 핸들을 요구하는 대부분의 함수에 사용할 수 있다.
( CreateEvent 함수 호출시에 lpEventAttributes를 이용하여 보안을 명시했다면 해당 보안사항에
만족하는 경우에만 이 핸들을 정상적으로 사용할 수 있다. )
CreateEvent 함수를 이용하여 이벤트 객체를 생성한 프로세스 또는 해당 프로세스가 생성한
추가적인 스레드는 WaitForSingleObject 같은 함수를 이용하여 해당 이벤트 객체에 이벤트가
발생하는지를 체크할수 있다. 예를들어, Test001 이라는 이벤트 객체를 생성하고 이 객체에
이벤트가 발생하는지 5초간 대기하면서 체크하려면 아래와 같이 코드를 구성하면된다.
추가적인 스레드는 WaitForSingleObject 같은 함수를 이용하여 해당 이벤트 객체에 이벤트가
발생하는지를 체크할수 있다. 예를들어, Test001 이라는 이벤트 객체를 생성하고 이 객체에
이벤트가 발생하는지 5초간 대기하면서 체크하려면 아래와 같이 코드를 구성하면된다.
HANDLE h_my_event = CreateEvent(NULL, TRUE, FALSE, "Test001");
if(h_my_event != NULL){
DWORD state = WaitForSingleObject(h_my_event, 5000);
if(state == WAIT_TIMEOUT) ...; // 5초간 이벤트가 발생하지 않은 경우
else if(state == WAIT_OBJECT_0) ...; // 이벤트가 발생한 경우
if(h_my_event != NULL){
DWORD state = WaitForSingleObject(h_my_event, 5000);
if(state == WAIT_TIMEOUT) ...; // 5초간 이벤트가 발생하지 않은 경우
else if(state == WAIT_OBJECT_0) ...; // 이벤트가 발생한 경우
// ...( 생략 )...
CloseHandle(h_my_event);
}
생성된 이벤트 객체에 신호를 발생하고 싶다면 SetEvent 함수를 사용하면 되고 발생된 신호를
해제하고 싶다면 ResetEvent 함수를 사용하면 된다.
}
생성된 이벤트 객체에 신호를 발생하고 싶다면 SetEvent 함수를 사용하면 되고 발생된 신호를
해제하고 싶다면 ResetEvent 함수를 사용하면 된다.
bManualReset에 TRUE를 명시해서 생성된 이벤트 객체는 신호가 발생하면 ResetEvent 함수를
호출할때까지 그대로 신호가 유지된다. 따라서 ResetEvent 함수를 호출하기 전까지 해당
이벤트 객체를 사용하는 모든 WaitForSingleObject 함수는 계속해서 WAIT_OBJECT_0를 반환하면서
수행을 완료할 것이다. 하지만 FALSE를 명시해서 생성된 이벤트 객체는 신호가 발생하면
WaitForSingleObject(또는 WaitForMultipleObject) 함수가 사용될때까지만 신호가 유지된다. 즉,
여러개의 스레드가 WaitForSingleObject 함수를 사용해서 이벤트를 체크하고 있더라도
그 중에 한개의 스레드가 WaitForSingleObject 함수를 호출하게 되면 자동으로 신호가 해제되고
다른 스레드는 체크할수 없게 된다. 그렇지만 신호가 발생된후에 WaitForSingleObject와 같은
신호 대기 함수가 한번도 호출이 되지 않는다면 그 신호는 계속 유지될것이다.
호출할때까지 그대로 신호가 유지된다. 따라서 ResetEvent 함수를 호출하기 전까지 해당
이벤트 객체를 사용하는 모든 WaitForSingleObject 함수는 계속해서 WAIT_OBJECT_0를 반환하면서
수행을 완료할 것이다. 하지만 FALSE를 명시해서 생성된 이벤트 객체는 신호가 발생하면
WaitForSingleObject(또는 WaitForMultipleObject) 함수가 사용될때까지만 신호가 유지된다. 즉,
여러개의 스레드가 WaitForSingleObject 함수를 사용해서 이벤트를 체크하고 있더라도
그 중에 한개의 스레드가 WaitForSingleObject 함수를 호출하게 되면 자동으로 신호가 해제되고
다른 스레드는 체크할수 없게 된다. 그렇지만 신호가 발생된후에 WaitForSingleObject와 같은
신호 대기 함수가 한번도 호출이 되지 않는다면 그 신호는 계속 유지될것이다.
여러개의 프로세스가 프로세스간 동기화의 목적으로 같은 이벤트 객체를 공유할 수 있으며,
아래와 같은 방법중에 한가지 형식을 사용하면 된다.
아래와 같은 방법중에 한가지 형식을 사용하면 된다.
-. CreateEvent 함수를 호출할때 lpEventAttributes 인자에 자식 프로세스에 대한 상속을 명시한 후,
CreateProcess 함수를 이용하여 프로세스를 생성하면 두 프로세스는 동일한 이벤트 객체를
공유하게 된다.
CreateProcess 함수를 이용하여 프로세스를 생성하면 두 프로세스는 동일한 이벤트 객체를
공유하게 된다.
-. DuplicateHandle 함수를 호출하여 이벤트 객체를 복사해서 사용하는 경우
-. 동일한 이름으로 OpenEvent 또는 CreateEvent 함수를 호출하는 경우
이렇게 생성된 이벤트 객체는 CloseHandle 이라는 함수를 이용해서 닫을수 있으며 직접 닫지
않더라도 해당 프로세스가 종료될때 시스템에 의해서 자동적으로 닫힌다. 하지만 해당
이벤트 객체가 여러개의 프로세스에 의해서 공유되어지는 경우에는 하나의 프로세스가
CloseHandle을 이용해서 닫더라도 해당 이벤트 객체는 제거되지 않고 공유하던 모든
프로세스가 해당 이벤트 객체를 닫는 경우, 마지막으로 닫는 시점에서 제거되어진다.
않더라도 해당 프로세스가 종료될때 시스템에 의해서 자동적으로 닫힌다. 하지만 해당
이벤트 객체가 여러개의 프로세스에 의해서 공유되어지는 경우에는 하나의 프로세스가
CloseHandle을 이용해서 닫더라도 해당 이벤트 객체는 제거되지 않고 공유하던 모든
프로세스가 해당 이벤트 객체를 닫는 경우, 마지막으로 닫는 시점에서 제거되어진다.
6. 함수의 요구사항
Window NT/2000/XP: Included in Windows NT 3.1 and later.
Windows 95/98/Me: Included in Windows 95 and Later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use kernel32.lib.
'Hello CE,Mobile' 카테고리의 다른 글
SendMessage() 와 PostMessage() 차이 (0) | 2009.12.11 |
---|---|
SendMessage() (0) | 2009.12.11 |
윈도우 동기화 (0) | 2009.12.02 |
CreateMutex() (0) | 2009.12.01 |
eVC4 에서 link시 CVT1102 에러 (0) | 2009.11.25 |