Inter-Process Communication (IPC)¶
Process 는 서로 독립된 자원을 가지고 있으며 서로의 연산 수행이 영향을 끼치지 못함.
여러 Processes가 같이 resources를 공유하고 Data를 주고 받아 작업을 수행하려면, Process간에 통신이 필요함.
크게 다음의 방식으로 수행됨.
- Signal 이용.
- Shared Memory 이용.
- Message Passing 이용.
Signal 이용.¶
Signal 은 Kernel 이 Process에게 비동기적인 알림이나 warning 등을 보내기 위한 방법 이나,
- 엄밀히는 Kernel이 Process에게 비동기적인 event를 알리기위한 방법임.
- 때문에 Kernel내부에서 Signal이 발생하여 Process에게 전달됨.
- 주로 예외 상황 이나 알림에 이용됨.
kill()
등의 System Call을 통해 특정 Process가 다른 Process에게 Kernel을 통해 Signal을 보내는 방식으로 Process 간 통신에도 제한적으로 사용이 가능함. : Light-weight IPC
단점은 Signal을 통한 IPC는 데이터를 전달할 수 없으며, 단지 Signal 번호만 전달 하므로 제한점이 있음.
즉, Signal 은 Kernel을 경유하여
특정 Process에서 다른 Process로 보내질 수 있음.
특정 Process에서 특정 Signal을 받을 경우 (=현재 실행되고 있는 Process가 Signal을 받을 경우,)
- Interrupt가 발생한 것처럼 현재의 실행을 멈추고,
- 해당 Signal을 처리하는 Signal Handler가 실행되며,
- 해당 Signal Handler가 종료하면 다시 이전의 실행을 재개하게 됨.
이를 이용하여,
- 특정 Signal을 받을 경우 수행되는 Signal Handler를
- 재정의해두고, 해당 Process에 해당 Signal을 보내는 방식으로
- IPC를 제한적으로 구현 하게 됨.
Linux의 경우, System Call인 sigaction
과 signal
을 통해
특정 Signal에 대한 처리를 구현할 수 있음.
- 특정 Signal의 기본동작을 변경:
sigaction
- 특정 Signal에 Signal Handler를 등록:
signal
Python을 이용하여 Signal Handler를 등록하는 예제는 다음과 같음.
- 다른 터미널에서
kill -SIGTERM <target_process_id>
를 수행해보거나, - 위 프로그램이 실행 중인 Terminal 에서
CTRL+c
로 interrupt를 발생시켜보면 - 구현한 Signal Handler의 동작을 확인할 수 있음.
- 종료시키려면
kill -9 <target_process_id>
를 수행.
참고: Signal 요약
Shared Memory (공유메모리)¶
OS 가 MMU (Memory Management Units)를 지원할 경우,
- 다수의 Process의 page table 에서
- 물리적으로 같은 RAM의 영역을 매핑할 경우,
- 해당 영역을 복수의 해당 Processes가 접근함으로서
- 효율적인 IPC가 가능해짐.
다른 이름으로 Shared Memory는 Shared Page라고도 불림.
Process 입장에서는 자신에게 할당된 Memory 영역을 읽고 쓰는 것과
같은 방식으로 다른 Process와 커뮤니케이션을 하는 것이기 때문에
매우 효율적인 커뮤니케이션이 됨: 가장 빠른 IPC 방법임.
- Kernel의 개입이 Signal을 이용하는 방식 등에 비해 거의 없다시피 함.
- 직접적으로 메시지를 주고 받는 방식인 socket등을 이용하는 방삭보다 속도가 빠름.
- 단, race condition 으로 인해 data consistency 등의 문제 발생 확률이 높음.
이를 위해서 사용되는 세부 방식은 크게 다음과 같음.
- 프로세스가 공유할 메모리 영역을 확보하는 system call을 사용.
- 메모리 대신에 file 등의 공유 자원을 이용하는 방식도 넓게 보면 공유메모리라고 볼 수 있음.
Python 등에서는 multiprocessing
모듈의 shared_memory
서브 모듈을 활용하여
프로세스 간에 메모리를 직접 공유할 수 있음.
Message Passing (메시지 전달)¶
IPC를 위한 방법 중 하나로, Processes가 서로 message를 주고 받아서 커뮤니케이션을 수행.
가장 직접적인 의미에서의 IPC로서 다음의 특징을 가짐.
- Kernel에 의해 주도되기 때문에 Signal 의 경우 처럼 data consistency에 문제가 없음: Kernel의 영향이 적은 Shared Memory와 차이점.
- 주고 받는 데이터가 Kernel을 통해 전달되기 때문에 Shared Memory보다 속도가 느림.
이를 위해서 사용되는 세부 방식은 다음과 같음.
- socket 이용: 네트워크 통신의 socket을 사용하므로 remote host의 process와도 통신이 가능.
- 기본적으로 양방향.
- 가장 복잡한 형태의 abstraction이 지원이 되어야 함.
- data serialization 에 기반하며, 다중 client 가 제공됨.
- 확장성이 가장 높은 편이나 다른 방식보다 속도가 느림.
- Remote Procedure Call (RPC):
- 원격지의 코드를 호출하는 기술로 대규모 트래픽이 요구되는 서버간 통신환경에서 많이 사용됨.
- Google의
gRPC
등의 프레임워크를 이용
- Pipe 사용:
- 일반적으로 단방향이고 부모/자식 프로세스에서만 사용가능 (이는
unnamed pipe
인 경우) named pipe
는 양방향이고 임의의 프로세스 간에 사용가능
- 일반적으로 단방향이고 부모/자식 프로세스에서만 사용가능 (이는
개인적으로 Pipe가 가장 쉽게 사용가능한 방법이라고 생각되나,
같은 host에서만 가능하고 보통 한 프로세스의 출력을 다른 프로세스의 입력으로 사용할 때 이용되는 것이라
확장성이 적음.
Python으로 socket을 이용한 예제는 다음과 같음: