. 통지객체

통지객체는 커널객체로, 이를 통하여 여러분의 스레드를 동기화할 수 있다. 개념을 설졍하자면 객체 하나를 생성하고 어던 벼화가 생길 경우에 스레드를 깨울 것인가 나타내는 속성들을 그 객체에 부여한다. 그리고 나서 여러분의 스레드를 멈추게하고, 객체의 통지를 기다리는 것이다. 원한다면 통지 객체를 파일시스템에 생기는 변화를 감지할 때 자동으로 신호 상태(signal)가 되는 아주특별하게 고안된 이벤트로 생각할 수 있다.

2. 통지객체의 내용

FindFirstChangeNotification()
FindNextChangeNotification()
FindCloseChangeNotification()

이렇게 3가지로 나누어지고 1번째는 생성 2번째는 변화가 감지되면 그 이벤트를 받는 역활을 하고 3번째는 생성된 객체를 해지한다.

물론 윈98에서는 이벤트로 받을 수 있는 정보가 한정적이기는 하지만 생각외로 요긴하게 쓰일 경우가 많다.


3. FindFirstChangeNotification() 함수

HANDLE FindFirstChangeNotification(
LPCTSTR lpPathName, // 감시할 경로
BOOL bWatchSubtree, // 서브 경로 감시 여부
DWORD dwNotifyFilter // 감시할 옵션
);

감시할 옵션으로는
FILE_NOTIFY_CHANGE_FILE_NAME 파일 이름 변경
FILE_NOTIFY_CHANGE_DIR_NAME 경로 이름 변경
FILE_NOTIFY_CHANGE_ATTRIBUTES 속성 변경 폴더/파일
FILE_NOTIFY_CHANGE_SIZE 파일 사이즈 변경
FILE_NOTIFY_CHANGE_LAST_WRITE 마지막 수정시간 변경 디렉토리/파일
FILE_NOTIFY_CHANGE_SECURITY 보안설정 변경 디렉토리/파일

위의 함수로 생성된 핸들을 루프안에서 WaitForSingleObject()를 이용하여 대기하다가
시그널이 들어오면..
FindNextChangeNotification() 를 이용하여 정보를 찾아낸다.

4. FindNextChangeNotification() 함수

BOOL FindNextChangeNotification(
HANDLE hChangeHandle // handle to change notification
);

간단한 예제를 들어보자...

while(g_bContinue)
{
WaitForSingleObject(hNotify, INFINITE);
PostMessage(ci.hwnd, WM_EX_CHANGENOTIFICATION, 0, 0);

FindNextChangeNotification(hNotify);
}
위에서 보다시피 루프안에는 루프를 끝낼 만한 이벤트가 없다. while문 안에 있는 부울린값 g_bContinue는 전역 변수로서 위 코드를 실행하는 스레드의 외부 에서 정해진다.
다시 말해 이 코드조작은 두개의 스레드가 있음을 암시하고 있다.

그리고, 마지막으로 감시를 중단할 경우는
BOOL FindCloseChangeNotification(
HANDLE hChangeHandle // handle to change notification
);
를 이용하여 감시를 해제할 수 있다.
이전에 g_bContinue를 FALSE상태로 바꾸고 위의 함수를 호출하는 형태로 해제가 가능하다.

그렇다면 위의 간단한 예제는 아래와 같이 변경되면 조금더 쓸모있는 코드가 될 수 있다.

while(g_bContinue)
{
WaitForSingleObject(hNotify, INFINITE);
if(!g_bContinue)
break;

PostMessage(ci.hwnd, WM_EX_CHANGENOTIFICATION, 0, 0);
FindNextChangeNotification(hNotify);
}

+ Recent posts