본문 바로가기

컴퓨터 공학/운영체제

프로세스 통신

프로세스는 기본적으로 각자 고유의 독립된 주소 공간을 가지며 서로의 주소 공간을 침범하는 것이 불가능하다. 

만약 침범하게 되면 흔히 블루 스크린이 발생하거나 메모리 침범 오류가 발생하며 프로그램이 죽어버린다. 

따라서 이번 시간에는 서로 다른 두 프로세스 간 어떤 방식으로 서로 데이터를 공유하는 지 알아보려한다. 

 

 

프로세스 간 통신은 IPC 라고 하며 대부분 위에 언급된 7가지 내에서 설명한다. 

물론 시대가 발전했으니 최신 프로세스 통신 방법이 더 생겼을 수도 있다. 

 

1. Message Passing

 

OS 커널에게 요청해 특정 프로세스에게 데이터를 전달하는 방법 (단 방향이기에 공유가 아니다)

 

 

Message Passing 은 커널 System Call 기능을 활용한 IPC 로 위와 같이 2가지 방식으로 나뉜다.

 

직접적인 방법은 왼쪽 그림처럼 프로세스 A 에서 메세지를 보낼 프로세스 B 를 명시해서 System Call send 를 호출하며 프로세스 B 에서는 System Call recieve 를 호출해 A 가 보내는 메세지를 받는다. 이 방법은 직접적으로 프로세스를 명시하기 때문에 1:1 통신만 가능하다. 

 

간접적인 방법은 오른쪽 그림처럼 프로세스 A 가 동일한 System Call 을 사용해 메세지 자체를 M 이라는 매개변수로 커널 주소 공간 내에 저장하며 프로세스 B 도 동일하지만 M 이라는 매개변수를 사용해 커널에서 받는 것이다. 따라서 이 방법을 사용하면 1:1 이 아닌 1:N 통신도 가능하다. 

 

2. Shared Memory, 공유 메모리

 

두 프로세스가 서로 공유가능한 메모리 영역을 할당 받아 데이터를 공유하는 방법

 

 

먼저 OS 커널에게 요청하여 두 프로세스 간 공유할 수 있는 메모리 영역을 따로 받는다. 이후 A 라는 프로세스가 공유 메모리 영역과 매핑된 자신의 주소 공간에 데이터를 쓸 경우(Write)  공유 메모리 영역에도 동일하게 데이터가 쓰여지며 이와 동시에 프로세스 B 에게 자신이 공유 데이터를 갱신한 것을 알린다. 그러면 프로세스 B 는 공유 메모리 영역에서 데이터를 읽어(Read) 마찬가지로 해당 공유 메모리 영역과 매핑된 자신의 고유 메모리에 해당 데이터를 가져와 결과적으로 두 프로세스 간 통신이 가능하게 된다. 공유 메모리 방식은 한 번 커널에게 메모리 영역을 할당 받으면 이후 커널의 시스템 콜 없이 통신이 가능하기 때문에 속도가 빠르지만 위에 언급했던 데이터 변경 후 신호를 보내는 것 그리고 프로세스 간 데이터 동기화 문제를 고려해 설계해야한다. 

 

3. PIPE, Named PIPE

 

자료구조 Queue 의 FIFO 데이터 입출력 형식을 따른 PIPE 파일을 생성해 데이터를 공유하는 방식.

여기서 PIPE 의 고유 이름을 사용자가 따로 명시하느냐에 따라 이름없는 혹은 이름있는 파이프가 된다. 

 

 

먼저 이름없는 파이프는 말 그대로 파이프 파일의 이름을 사용자가 따로 명시 하지 않고 생성한 뒤 파이프 통신을 사용하는 방식이다. 위의 그림과 같이 A 라는 프로세스에서 파이프에 사용될 길이 2 짜리 배열을 생성하고 pipe(Array); 함수를 호출하게 되면 커널은 fork(); 하여 프로세스 A 의 자식을 만들고 파이프 파일을 만들어준다. 이후 한 쪽 프로세스에서 데이터를 Array[0] 에 입력하게 되면 다른 한 쪽에서는 Array[1] 에서 동일한 데이터를 가져옴으로써 부모, 자식 프로세스 간 통신을 하게 된다.

 

단, 파이프 통신은 단방향 통신이기때문에 한 쪽 프로세스가 읽기를 한다면 다른 한 쪽에서는 쓰기만을 해야하고 기본적으로 파이프 통신 간 한 쪽에 데이터를 Read 혹은 Write 를 하게 될 경우 다른 한 쪽에서 상응하는 동작을 취하기 전에는 기본적으로 Blocked 상태로 대기하게 된다. 따라서 설계 오류 시 무한정 대기하는 상황이 발생할 수 있다. 

 

 

이름있는 파이프의 경우에는 위와 같이 파이프 파일을 이름을 명시해 생성하며 서로 다른 두 프로세스 간 해당 파일을 읽기 혹은 쓰기 모드로 열어 Read/Write 를 진행하며 데이터를 통신하게 된다. 단, 실제로 파이프 파일에 데이터가 씌여지는 것이 아닌 실제 데이터는 커널 내부에 씌여진다.

 

이름있는 파이프의 경우에도 기본적으로는 이전의 이름없는 파이프와 동일하게 단방향 통신이며 어떻게 보면 두 프로세스 간 동기식 통신이라 할 수 있는 Blocked 모드로 데이터를 공유한다. 물론 프로세스에서 파일 open 시 매개변수를 통해 NonBlocking 모드로 사용할 수 있지만 Unix 의 규약인 POSIX 에서 NonBlocking 에 대해 따로 정의하지 않았기 때문에 OS 마다 다르게 동작할 수 있다. 따라서 해당 모드의 사용을 권장하지 않는다고 한다. 

 

4. Message Queue

 

프로세스 간 메세지 지향 미들웨어(Message Oriented Middleware)를 사용해 통신하는 방식.

여기서 미들웨어란 또 하나의 응용 프로그램이라고 생각하면 된다. 

 

따라서 어떠한 미들웨어를 사용하느냐에 따라 해당 프로그램의 정책이나 동작방식에 따라 통신 방식에 차이가 존재한다.

하지만 기본적으로는 비동기식으로 통신하기에 위에 언급한 OS 커널을 사용한 동기식 통신보다 빠르며 OS 내부 시스템 함수에 의존하지 않고 좀 더 자유로운 확장과 서비스 운영이 가능하다. 

 

5. Memory Mapped File

 

프로세스는 작업 수행 간 데이터를 가져오기 위해 디스크에서 자신의 프로그램의 파일을 가져와 열어서 사용한다. 이때 열린 파일을 프로세스의 가상 주소 공간에 매핑하여 프로세스에서 직접 파일의 주소 공간에 접근할 수 있고 이렇게 매핑 된 파일을 Memory Mapped File 이라고 한다. IPC 에서는 이러한 Memory Mapped FIle 을 바라보는 부모, 자식 프로세스 간 통신으로 사용할 수 있다. 

 

이 방법은 대용량 파일을 공유하는 부모, 자식 프로세스 간 유용하게 사용가능하며 일반적인 파일 입출력 보다 빠르게 데이터 통신이 가능하다. 

 

6. File 

 

어떻게 보면 위에 언급된 모든 방식의 기초가 되는 IPC. 하나의 파일을 두 프로세스가 공유한다. 하지만 사용자가 직접 파일을 디렉토리에 생성하고 통신하는 방법은 위의 다른 방식보다 비효율적 이기에 거의 사용하지 않는다. 

 

7. Socket 

 

가장 어려운 개념이지만 소켓도 어떻게 보면 위의 언급한 다른 IPC 처럼 파일(=소켓)을 활용한 프로세스 간 통신이다. 

 

 

간단하게 원리만 살펴보자. 

 

응용 프로그램이 네트워크를 통해 인터넷으로 데이터를 보내려면 TCP/IP 프로토콜을 따라야하며 그때 사용되는 파일이 바로 소켓이다. 소켓을 사용한 통신 간에는 서로를 식별하기 위한 정보로 IP 와 Port 번호를 받는다. 이때 OS 는 소켓을 통해 전달할 데이터의 일부를 특정 크기의 버퍼로 쪼개어 보내는데 버퍼에 쌓인 정보는 Segement 로 더 작게 쪼개져 Message Packet 이 되어 인터넷으로 전송된다. 이후 수신측은 해당 Message Packet 에서 다시 Segement 를 꺼내어 그것을 자신의 버퍼에 넣고 이를 소켓을 통해 응용 프로그램의 프로세스에게 전달하게 되는데 이러한 IPC 를 소켓 통신이라고 한다. (해당 내용은 향후 네트워크 TCP/IP 에서 보다 자세히 다뤄보려 한다)

 

여기까지 프로세스 간 통신인 IPC 에 대해 알아보았다. 그런데 여기서 이렇게 서로 통신하는 과정에서 같은 데이터를 서로 다른 두 프로세스 간 거의 동시에 수정을 하게 되었을 경우에 정보가 얽히지 않도록 데이터의 무결성을 보장해야한다. 그래서 개발자들은 프로세스 동기화를 활용해 프로세스 간 주고 받는 데이터의 무결성을 보장해줘야하며 다음 시간에는 프로세스 동기화에 대해 알아보려고 한다.

'컴퓨터 공학 > 운영체제' 카테고리의 다른 글

프로세스 동기화 문제  (1) 2023.01.27
프로세스 동기화  (0) 2023.01.25
CPU 스케쥴링  (0) 2023.01.21
프로세스 관리  (0) 2023.01.19
프로세스(Process), 스레드(Thread)  (0) 2023.01.19