VII : 프로세스간 통신 (IPC) 1
뇌를 자극하는 윈도우즈 시스템 프로그래밍 을 읽고 정리한 문서입니다 ;)
프로세스간 통신 (IPC) 의 의미
만일 서로 통신하고자 하는 프로세스가 서로 만날 수 있는 여건, 즉 공유 메모리 등이 존재한다면 프로세스간 통신은 매우 쉬워진다. 하지만, 이러한 여건이 되지 않는다면 보조 수단이 필요하다.
프로세스들은 모두 가상 메모리 시스템 내에서 자신만의 메모리 주소 체계를 가지므로, 서로의 메모리에 쉽게 접근할 수 없다. 이는 프로세스간 메모리 침범을 막아 안정성을 높이기 위함이다.
메일슬롯 방식의 IPC
메일슬롯은 파이프와 더불어 대표적인 IPC 기법이다. 메일슬롯은 편지를 넣을 수 있는 가느다란 우체통의 입구를 의미한다. 즉, 메일슬롯의 기본 원리는 데이터를 주고 받기 위해서 프로세스가 우체통을 마련하는 것으로 볼 수 있다.
메일슬롯 구성을 위해 필요한 요소
Receiver에 해당하는 프로세스는 우체통을 생성해야 한다.
HANDLE CreateMailSlot(
LPCTSTR lpName,
DWORD nMaxMessageSize,
DWORD lReadTimeout,
LPSECURITY_ATTRIBUTES lpSA
);
LPCTSTR lpName
: 생성하는 메일슬롯의 이름을 결정하는 데 사용되고, 이것이 곧 주소가 된다.\\<computername>>\mailslot\<path>
의 형식을 가지고,computername
이.
인 경우는 자기 자신을 의미하고,*
인 경우에는 같은 네트워크의 모든 호스트를 의미한다.
DWORD lReadTimeout
: 메일 슬롯에서 읽기를 수행할 때 만일 비워져 있다면 데이터가 채워질 때까지 리턴하지 않아 블로킹 상태가 되지만, 이 때 타임아웃을 지정할 수 있다.
Sender에 해당하는 프로세스는 Receiver가 만들어 놓은 메일슬롯의 이름을 알아야 한다. 이후 CreateFile()
과 WriteFile()
을 통해 메일슬롯과 연결하여 데이터를 보내게 된다.
메일슬롯은 윈도우 파일 시스템을 기반으로 구현되어 있기에, 파일을 다루는 함수를 사용한다.
BOOL ReadFile(
HANDLE hFile,
LPVOID lpBuffer,
DWORD nNumberOfBytesToRead,
LPDWORD lpNumberOfBytesRead,
LPOVERLAPPED lpOverlapped
);
LPVOID lpBuffer
: 읽어 들일 데이터를 저장할 버퍼DWORD nNumberOfBytesToRead
: 읽어 들일 데이터의 최대 크기LPDWORD lpNumberOfBytesRead
: 읽어 들인 데이터의 크기
CreateFile()
에서 파일의 개방 모드를 GENERIC_WRITE
로 해야 데이터를 써낼 수 있고, 파일의 생성방식을 결정받는 인자는 OPEN_EXISTING
을 사용해야 존재하는 메일슬롯에 연결할 수 있게 된다.
BOOL WriteFile(
HANDLE hFile,
LPCVOID lpBuffer,
DWORD nNumberOfBytesToWrite,
LPDWORD lpNumberOfBytesWritten,
LPOVERLAPPED lpOverlapped
);
LPCVOID lpBuffer
: 전송할 데이터가 저장되어 있는 버퍼를 지정한다DWORD nNumberOfBytesToWrite
: 전송할 데이터 크기를 지정한다LPDWORD lpNumberOfBytesWritten
: 함수 호출 완료 후 전송된 실제 크기를 받아올 주소이다.
메일슬롯 IPC
메일슬롯은 한쪽 방향으로만 메시지를 전달할 수 있다. 따라서 양방향으로 통신하기를 원한다면 두 개의 메일슬롯을 생성해야만 한다.
메일슬롯은 브로드캐스팅 방식의 통신을 지원한다. 하나의 Sender 가 한 번의 메시지 전송으로 여러 Receiver에게 동일한 메시지를 전송하는 것이 가능하다.
Signaled vs Non-Signaled
커널 오브젝트는 두 가지 상태를 지닌다. 이는 리소스에 특정 상황이 발생되었음을 알리기 위한 용도로 사용된다.
하나는 Signaled 상태로서 신호를 받은 상태이고, 나머지 하나는 Non-Signaled 상태로서 신호를 받지 않은 상태이다. 이러한 상태 데이터 또한 커널 오브젝트의 멤버로 들어가 있다.
커널 오브젝트의 상태는 특정 리소스에 특정 상황이 발생하였음을 알려주기 위해 존재하는 것이지만, 이 특정 상황이라는 것이 리소스마다 다르다. 때문에 커널 오브젝트의 상태가 변하는 시점은 커널 오브젝트의 종류에 따라서 달라진다.
프로세스 커널 오브젝트는 프로세스가 생성될 때 만들어진다. 이렇게 커널 오브젝트가 생성되면 상태는 Non-Signaled 상태에 놓이게 되고, 프로세스가 종료될 때 Signaled 상태로 변경되게 된다.
즉 프로세스 커널 오브젝트의 상태는 일단 Signaled가 되면 다시 Non-Signaled 상태로 변경되지 않는다.
커널 오브젝트의 상태를 확인하는 함수
DWORD WaitForSingleObject(
HANDLE hHandle,
DWORD dwMilliseconds
);
DWORD dwMilliseconds
: 첫 번째 인자로 전달된 핸들이 가리키는 커널 오브젝트가 Signaled 상태가 되었을 때 함수가 리턴받게 되는데, 이 때 얼마나 기다릴 지 타임아웃을 설정하는 값이다.
이 함수가 반환하는 상황은 다양하므로 함수 호출이 완료된 후에 반환값을 확인해야 한다.
WAIT_OBJECT_0
: 커널 오브젝트가 Signaled 상태가 되었을 때 반환되는 값WAIT_TIMEOUT
: 커널 오브젝트가 Signaled 상태가 되지 않고 타임아웃이 만료될 때의 값WAIT_ABANDONED
: 소유 관계와 관련하여 비정상적 오류 상태일 때 반환되는 값
이는 자식 프로세스가 종료될 때 까지 대기하였다가 그 결과를 받아서 사용하는 부모 프로세스 입장에서 사용할 수 있는 함수이다.
이것과 비슷하게, 여러 커널 오브젝트의 상태 변화를 기다릴 수 있는 WaitForMultipleObjects()
함수 또한 존재한다.
이것만은 알고 갑시다
- 프로세스간 통신 기법이 별도로 존재하는 이유
- 프로세스는 개별적으로 독립적인 메모리 공간을 유지한다. 따라서 둘 이상의 프로세스가 데이터를 주고 받기 위해서는 윈도우 운영체제에서 제공하는 기능상의 도움을 받아야 한다.
- 메일슬롯의 특성
- 대표적인 프로세스 통신기법으로 메일슬롯 기법이 있다. 단 이는 단방향 통신과 브로드캐스팅 방식을 지원하는 통신기법이다.
- 커널 오브젝트의 두 가지 상태가 지니는 의미
- 커널 오브젝트는 Signaled 상태와 Non-Signaled 상태 둘 중 하나의 상태에 놓이게 된다. 그리고 이 상태는 나머지 다른 하나의 상태로 변경되는데, 상태가 변경되는 시점은 커널 오브젝트의 종류에 따라 다르다.
WaitForSingleObject
및WaitForMultipleObjects
함수와 커널 오브젝트WaitForSingleObject
함수는 커널 오브젝트의 상태 변화를 감지하는 역할을 한다. 커널 오브젝트가 Non-Signaled 상태에 있을 때는 블로킹 상태에 있다가, Signaled 상태가 되면 함수를 빠져나오게 된다.
- 종료 코드
- 프로세스의 종료 코드를 받기 위해서는
GetExitCodeProcess()
함수를 호출하면 되고, 이 경우 해당 프로세스의 종료 이벤트를 대기하기 위해WaitForSingleObject
함수를 사용할 것이다.
- 프로세스의 종료 코드를 받기 위해서는
'공부한 이야기 > 윈도우 OS' 카테고리의 다른 글
IX : 스케줄링 알고리즘과 우선순위 (0) | 2023.04.29 |
---|---|
VIII : 프로세스간 통신 (IPC) 2 (0) | 2023.04.29 |
VI : 커널 오브젝트와 오브젝트 핸들 (0) | 2023.04.29 |
V : 프로세스의 생성과 소멸 (0) | 2023.04.29 |
IV : 컴퓨터 구조에 대한 두번째 이야기 (0) | 2023.04.29 |