윈도우즈 시스템 프로그래밍 7장-세션3
시그널 VS 논시그널
커널 오브젝트는 두 가지 상태를 가지고 있다.
이 두 개의 상태는 리소스에 특정 상황이 발생되었음을 알리기 위한 용도로 사용된다.
상태에 대한 이해
상태는 변화 가능성을 내포한 개념이다.
즉 커널 오브젝트의 상태(시그널과 논시그널
)역시 어떤 작용에 의하여 변할 수 있음을 의미한다.
커널 오브젝트의 상태가 시그널이면 상태 정보를 저장하는 멤버 변수가 TRUE의 값을 가지게 되며, 논시그널 상태이면 FALSE의 값을 가지게 된다.
프로세스의 커널 오브젝트 상태
커널오브젝트의 상태라는 것은 특정 상황의 발생을 알려주는 역할로 사용된다.
여기에서 중요한 사실은 특정 상황이라는 것이 리소스마다 다르기 때문에 커널 오브젝트의 상태 변화 시점은 커널 오브젝트의 종류에 따라 달라진다.
프로세스 커널 오브젝트는 처음 생성되면 논시그널 상태이다.
그러다가 프로세스가 변경되면 시그널 상태로 변하고 이 과정들은 windows운영체제에 의하여 자동으로 이루어진다.
그렇다면 시그널에서 논시그널 상태로 변하는 시점은 언제일까?
결과적으로는 불가능하다.
프로세스는 종료가 되면 새로 다시 실행하지 않는 이상 다시 살릴 수 없기 때문이다.
상태 확인 함수
WaitForSingleObject는 멤버 변수로 상태 확인을 원하는 커널 오브젝트의 핸들
과 DWORD 기다릴 최대 시간
을 가지게 된다.
예를 들어 DWORD에 infinite를 인자로 전달하면, 커널 오브젝트가 시그널 상태가 될 때까지 반환하지 않고 무한정 기다리게 된다.
상태확인함수2
WaitForMultipleObjects를 쓰면 보다 복잡한 상황에서의 상태를 확인할 수 있다.
만약 커널 오브젝트가 둘 이상고 이 커널 오브젝트들이 배열로 묶여있을 때에 활용을 하면 편하다.
멤버 변수
DWORD로 핸들 개수 전달
const로 핸들을 저장중인 배열의 주소 정보 전달
BOOL타입으로 관찰대상이 모두 시그널 될 떄까지 기다릴 것인지 하나라도 시그널되면 반환할 것인지 결정
DWORD로 타임아웃을 설정
언제 사용해야할까
저자의 요구사항을 정리해보면, 부모가 두개의 자식 프로세스를 생성하되 이 둘의 역할은 동일하다는 것을 알 수 있다.
그렇다면 우리가 파일을 작성할 때에도 자식 프로세스를 두개 만들어야할까?
굳이 그렇게 하기보다는 범위를 지정해서 child프로세스를 두 개의 프로세스처럼 생성하는 것이 보다 효율적일 것이다.
코드를 통해 보는 내용
WaitForSingleObject(pi1.hProcess, INFINITE);
WaitForSingleObject(pi2.hProcess, INFINITE);
여기 이 코드는 쓰레드를 잠깐 기다렸다가, 각각 원하는 계산을 완료하고 종료할 때까지 기다리는 함수이다.
그런데, 위 코드는 사실 기다리는 대상이 다를뿐 본질적으로 하고자하는 행위는 같기 때문에 WaitForMultipleObjects()
함수를 사용하여 한 줄의 코드로 정리하는 것이 가능하다.
Multiple Obejcts함수
4개의 매개변수로 이루어져있으며 각각의 변수는 다음과 같은 의미이다.
- ncount
첫번째 매개변수인 DWORD타입인 ncount는 핸들의 개수를 의미한다. - lpHandles
const HANDLE타입인 두번째 매개변수에는 핸들을 저장하는 배열의 주소정보가 담긴다. - bWaitAll
관찰대상이 하나라도 시그널 상태가 되면 반환할 것인지, 모두 시그널 상태가 되었을 때 반환할 것인지를 결정한다. - dwMilliseconds
커널 오브젝트가 시그널 상태가 될 때까지 얼마나 기다릴지를 지정하는 DWORD타입의 매개변수이다.코드로 학습하기
HANDLE handles[2] = { pi1.hProcess, pi2.hProcess }; DWORD result = WaitForMultipleObjects(2, handles, TRUE, INFINITE);
여기에서 유의할점은 HANDLE자체가 포인터처럼 작동하기 때문에, 굳이 *을 쓰지 않아도 배열의 주소정보를 담을 수 있다.
간단하게 설명하자면 HANDLE은 객체를 식별하기 위해 이미 운영체제 내부에 있는 어떤 리소스의 정수를 정수로 치환한 값이기 때문에 HANDLE을 집어넣으면 배열의 주소정보가 알아서 담기게 된다.
댓글남기기