HotFoxy
불여우의 전직 이야기
게임 서버 개발자가 되어 보죠!
전체 방문자
오늘
어제
  • 분류 전체보기 (135)
    • 연구한 이야기 (26)
      • 깊게 공부해보기 (7)
      • 문제 해결 이야기 (12)
      • 맡은 업무 이야기 (6)
    • 전직 이야기 (0)
      • 1년이라는 시간 (5)
      • 프로카데미 이야기 (5)
    • 공부한 이야기 (87)
      • 알고리즘 (7)
      • 리눅스 (11)
      • 클라우드 (24)
      • 윈도우 OS (17)
      • 윈도우 소켓 프로그래밍 (11)
      • 네트워크 (16)
      • Docker & K8S (0)
      • 기타 (1)
    • 자격증 이야기 (12)
  • MSB : Mad Square's Brawl
  • GITHUB

인기 글

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
HotFoxy

불여우의 전직 이야기

공부한 이야기/윈도우 OS

VII : 프로세스간 통신 (IPC) 1

2023. 4. 29. 21:53

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
    '공부한 이야기/윈도우 OS' 카테고리의 다른 글
    • IX : 스케줄링 알고리즘과 우선순위
    • VIII : 프로세스간 통신 (IPC) 2
    • VI : 커널 오브젝트와 오브젝트 핸들
    • V : 프로세스의 생성과 소멸
    HotFoxy
    HotFoxy
    1년 동안의 고군분투 전직 이야기! ..가 완료되어, 게임개발자로 살아남는 이야기!

    티스토리툴바