커널 오브젝트의 상태 (State)
- 리소스에 특정 상황이 발생되었음을 알리기 위한 용도
- 커널 오브젝트를 구성하는 멤버 변수 중 하나는 커널 오브젝트의 상태 정보를 저장
- 커널 오브젝트의 상태 변화 시점은 커널 오브젝트에 종류에 따라 상이
Signaled 상태
- 신호를 받은 상태
- TRUE
Non-Signaled 상태
- 신호를 받지 않은 상태
- FALSE
- 커널 오브젝트가 생성되면 커널 오브젝트의 상태는 Non-Signaled
프로세스 커널 오브젝트의 상태
- 프로세스가 생성될 때 프로세스 커널 오브젝트가 생성 (Non-Signaled)
- 프로세스가 종료되면 Signaled 상태로 변경
- Windows 운영체제에 의해 변경
- 프로세스 커널 오브젝트가 Non-Signaled 상태인 경우 프로세스가 실행 중인 상태
- 프로세스 커널 오브젝트가 Signaled 상태인 경우 프로세스가 종료된 상태
- 프로세스 커널 오브젝트는 Signaled 상태인 경우 Non-Signaled 상태로 변경되지 않는다
- 종료된 프로세스는 다시 실행해야 한다
WaitForSinggleObject 함수
DWORD WaitForSingleObject(
[in] HANDLE hHandle,
[in] DWORD dwMilliseconds
);
- 커널 오브젝트의 상태 확인
- 커널 오브젝트가 Signaled 상태인 경우 반환
- hHandle
- 커널 오브젝트의 핸들
- dwMilliseconds
- 커널 오브젝트가 Signaled 상태가 될 때 까지 기다릴 수 있는 최대 시간 (Time Out)
- INFINITE 인 경우 커널 오브젝트가 Signaled 상태가 될 때 까지 대기
- 반환 값
- WAIT_ABANDONED
- 소유 관계와 관련된 오류 발생
- WAIT_OBJECT_0
- 커널 오브젝트가 Signaled 상태
- WAIT_TIMEOUT
- 커널 오브젝트가 Signaled 상태가 되지 않고 dwMilliseconds 를 경과
- WAIT_FAILED
- 함수 실패
- WAIT_ABANDONED
WaitForMultipleObjects 함수
DWORD WaitForMultipleObjects(
[in] DWORD nCount,
[in] const HANDLE *lpHandles,
[in] BOOL bWaitAll,
[in] DWORD dwMilliseconds
);
- 배열 내 커널 오브젝트들의 상태 확인
- 하나 또는 전체가 Signaled 상태인 경우 반환
- nCount
- 배열에 저장된 핸들의 수
- lpHandles
- 핸들이 저장된 배열의 주소
- bWaitAll
- TRUE 인 경우 모든 커널 오브젝트가 Signaled 상태인 경우 반환
- FALSE 인 경우 하나의 커널 오브젝트라도 Signaled 상태인 경우 반환
- dwMilliseconds
커널 오브젝트 상태 확인이 필요한 상황
- 첫 번째 자식 프로세스는 1 부터 5 까지 덧셈 후 결과 반환
- 두 번째 자식 프로세스는 6 부터 10 까지 덧셈 후 결과 반환
- 부모 프로세스는 반환 값을 덧셈 후 결과 출력
자식 프로세스 (링크)
// Adder Child Process
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
int _tmain(int argc, TCHAR* argv[])
{
DWORD b = _tstoi(argv[1]);
DWORD e = _tstoi(argv[2]);
DWORD sum = 0;
while (b <= e)
{
sum += b;
++b;
}
return sum;
}
- _tstoi 함수를 통해 문자열을 정수로 변환
- argv[1] 부터 argv[2] 까지의 합을 반환
부모 프로세스 (링크)
// Adder Parent Process
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
int _tmain(void)
{
DWORD sum1;
DWORD sum2;
STARTUPINFO si;
PROCESS_INFORMATION pi;
// sum1
SecureZeroMemory(&si, sizeof(si));
SecureZeroMemory(&pi, sizeof(pi));
si.cb = sizeof(si);
TCHAR commandLine1[] = _T("AdderChildProcess.exe 1 5");
CreateProcess(NULL, commandLine1, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
WaitForSingleObject(pi.hProcess, INFINITE);
GetExitCodeProcess(pi.hProcess, &sum1);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
// sum2
SecureZeroMemory(&si, sizeof(si));
SecureZeroMemory(&pi, sizeof(pi));
si.cb = sizeof(si);
TCHAR commandLine2[] = _T("AdderChildProcess.exe 6 10");
CreateProcess(NULL, commandLine2, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
WaitForSingleObject(pi.hProcess, INFINITE);
GetExitCodeProcess(pi.hProcess, &sum2);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
// sum1 + sum2
_tprintf(_T("%d\n"), sum1 + sum2);
return 0;
}
- "AdderChildProcess.exe 1 5"
- 자식 프로세스를 실행하고 1 ~ 5 의 합을 계산한다
- "AdderChildProcess.exe 6 10"
- 자식 프로세스를 실행하고 6 ~ 10 의 합을 계산한다
- WaitForSingleObject 함수를 통해 자식 프로세스의 커널 오브젝트가 Signaled 상태가 될 때 까지 Blocking
- GetExitCodeProcess 함수를 통해 자식 프로세스의 커널 오브젝트 내 종료 코드 획득
- 총 합 출력
실행 결과
- 1 ~ 10 의 합인 55 출력
참고 자료
프로세스 생성
CreateProcess 함수를 통해 프로세스를 생성해보자 processthreadsapi.h 헤더는 CreateProcess를 UNICODE 전처리기 상수의 정의에 따라,이 함수의 ANSI 또는 UNICODE 버전을 자동으로 선택하는 별칭으로 정의하고
pharan.tistory.com
https://learn.microsoft.com/ko-kr/windows/win32/api/synchapi/nf-synchapi-waitforsingleobject
WaitForSingleObject 함수(synchapi.h) - Win32 apps
지정된 개체가 신호 상태가 되거나 시간 제한 간격이 경과할 때까지 기다립니다.
learn.microsoft.com
https://learn.microsoft.com/ko-kr/windows/win32/api/synchapi/nf-synchapi-waitformultipleobjects
WaitForMultipleObjects 함수(synchapi.h) - Win32 apps
지정된 개체 중 하나 또는 전부가 신호 상태 또는 시간 제한 간격이 경과할 때까지 기다립니다.
learn.microsoft.com
atoi, _atoi_l, _wtoi, _wtoi_l
자세한 정보: atoi, _atoi_l, _wtoi, _wtoi_l
learn.microsoft.com
https://www.youtube.com/playlist?list=PLVsNizTWUw7E2KrfnsyEjTqo-6uKiQoxc
뇌를 자극하는 윈도우즈 시스템 프로그래밍
www.youtube.com
'Windows' 카테고리의 다른 글
핸들 테이블과 핸들의 상속 (0) | 2024.05.12 |
---|---|
메일 슬롯 방식 IPC (0) | 2024.05.07 |
커널 오브젝트와 핸들 (0) | 2024.04.26 |
표준 검색경로 (0) | 2024.04.11 |
프로세스 생성 (0) | 2024.04.10 |