✔︎ IPC(Inter Process Communication)란 ?
독립적 구조를 가진 프로세스 간의 통신을 가능하도록 해주는 것
프로세스가 작업 중 다른 프로세스의 공간을 침범(wirte)해 버린다면 (예를 들어 다른 프로세스의 스택을 건드리는 경우) 문제가 발생한다.
이를 비정상 공유라고 하는데 커널은 이것을 막기 위해 "Protection"을 한다.
Protection이란 ?
임의의 프로세스가 다른 프로세스의 주소 공간에 접근하는 것을 금지하는 것이다.
오직 신뢰할 수 있는 커널만이 모든 프로세스의 주소 공간에 접근할 수 있도록 하며
프로세스는 커널이 제공하는 IPC 설비를 이용해 프로세스 간 통신을 할 수 있게 된다.
Kernel이란 ?
운영체제 자체도 소프트웨어이므로 메모리에 올라가야 사용할 수 있다.
하지만 메모리 공간의 제약으로 운영체제 중 항상 필요한 부분만을 메모리에 올려놓고, 그렇지 않은 부분은 필요할 때만 메모리에 올려 사용한다.
이때 메모리에 상주하는 운영체제의 부분을 커널이라고 한다. (그래서 보통 OS라고 하면 커널을 말하는 것이다.)
정리하자면 커널은 메모리에 상주하는 부분으로써 운영체제의 핵심 부분을 뜻한다.
✔︎ IPC가 필요한 이유 (프로세스 간 통신이 필요한 이유)
정보 공유 (Information Sharing):
여러 사용자가 동일한 정보에 액세스 할 필요가 있을 수 있다.
가속화 (Computation Speed-up):
특정 작업 (task)을 여러 개의 서브 작업(sub-task)로 쪼개어 프로세스의 병렬성을 키움으로써 처리 속도를 높일 수 있다.
이 때 메인 작업과 서브 작업은 서로 통신의 필요성이 생긴다.
모듈화 (Modularity):
특정한 시스템 기능을 별도의 프로세스(스레드)로 구분해 모듈화된 시스템을 구성할 수 있다.
이 때 모듈 간의 통신이 필요하다.
편의성 (Convenience):
다수의 사용자가 동시에 여러가지 작업을 수행할 수 있다.
IPC가 필요한 예로는 다음과 같은 것이 있다.
1. LCD에 출력할 문자 메세지를 전달
2. 센서로부터 읽은 값을 다른 프로세스한테 전달
3. 디스플레이에 그릴 비트맵 데이터를 전달
✔︎ IPC 종류
IPC의 종류는 크게 메시지 전달 (Message Passing)과 메모리 공유 (Shared Memory)로 나뉜다.
메시지 전달 (Message Passing) | 공유 메모리 (Shared Memory) |
커널을 통해 메세지를 전달하는 방식으로 자원이나 데이터를 주고 받는다. | 공유 메모리 영역을 구축하고 공유영역을 통해 자원이나 데이터를 주고 받는다. |
커널을 이용하기 때문에 구현이 비교적 쉽다. | 커널 의존도가 낮아 속도가 빠르고 통신이 자유롭다. |
시스템 콜이 필요하며 이로 인해 오버헤드가 발생한다. | 자원과 데이터를 공유하기 때문에 동기화 이슈가 발생한다. |
Pipe, Signal, Message Queueing, Socket 등 | 공유 메모리, 메모리 맵 등 |
메시지 전달 (Message Passing)
- 커널이 제공하는 API를 이용해 커널 공간을 위해 통신한다.
- 메시지 큐를 사용해 송신 프로세스는 큐에 enqueue, 수신 프로세스는 큐에 dequeue하며 상호간 통신한다.
- 메시지 큐는 커널 단에서 관리된다.
1. 익명 PIPE
익명의 Pipe를 통해 동일한 부모 프로세스를 가진 프로세스들 간에 단방향 통신을 지원한다.
FIFO 구조이며 연결된 프로세스 중 하나는 데이터를 '쓰기'만 하고, 다른 하나는 데이터를 '읽기'만 할 수 있다.
이러한 구조를 한쪽 방향으로만 통신이 가능한 반이중 통신이라고 부른다.
따라서 양쪽으로 모두 송/수신을 하고싶다면 2개의 파이프를 만들어야 한다.
쌍방향 통신을 위해서는 '쓰기'용 PIPE 하나 '읽기'용 PIPE 하나를 따로 만들어야 한다.
read(), write()가 기본적으로 block 모드로 작동하므로 프로세스는 read가 끝나기 전에는 write를 할 수 없다.
block 모드란 ?
프로세스 간의 통신에서 송신 프로세스가 메시지를 전송할 때, 수신 프로세스가 메시지를 받을 준비가 되어 있지 않으면 송신 프로세스가 대기(block) 상태에 빠지는 모드를 말한다.
이 모드에서 송신 프로세스는 메시지를 전송한 후, 수신 프로세스가 준비될 때까지 대기한다.
이러한 방식으로 IPC가 동작하면, 송신 프로세스와 수신 프로세스 간에 동기화를 유지할 수 있다.
이는 메시지의 무결성을 보장하고, 데이터 손실을 방지할 수 있어 중요하다.
반면에 non-block 모드에서는 송신 프로세스가 메시지를 전송한 후에도 수신 프로세스의 상태와 관계없이 즉시 반환된다.
따라서 이 모드에서는 송신 프로세스와 수신 프로세스 간의 동기화가 유지되지 않을 수 있다.
이러한 경우, 데이터 손실이나 일관성 문제가 발생할 수 있다.
매우 간단하게 사용할 수 있어 단순한 데이터 흐름을 가질 땐 파이프를 사용하는 것이 효율적이다.
전이중 통신을 위해 2개를 만들어야 할 때는 구현이 복잡해지게 된다.
2. Named PIPE
프로세스들 간에 단방향 통신을 지원하며 프로세스들이 Pipe 이름만 알면 통신이 가능하다.
익명의 Pipe와 마찬가지로 FIFO 구조이며 생성된 Pipe에 대해 읽기, 쓰기만 가능하다.
따라서 전이중 통신을 위해서는 익명 Pipe처럼 2개를 만들어야 한다.
Named PIPE의 생성은 mkfifo를 통해 이뤄지는데, mkfifo가 성공하면 명명된 파일이 생성된다.
anonymous pipe vs named pipe
1. 이름 유무
- anonymous pipe는 이름이 없는 파이프이며, 일반적으로 한 프로세스 내에서 생성되고 부모-자식 프로세스 간의 통신에 사용된다.
- named pipe는 이름이 있는 파이프로서, 시스템 전체에서 접근 가능하며 다른 프로세스 간의 통신에 사용된다.
2. 생성 방법
- anonymous pipe는 pipe() 시스템 콜을 호출하여 생성된다.
- named pipe는 mkfifo() 시스템 콜을 호출하여 생성된다.
3. 파일 시스템 관점
- anonymous pipe는 파일 시스템에는 등록되지 않는다.
- named pipe는 파일 시스템에 등록되며, 파일처럼 접근할 수 있다.
4. 통신 방향
- anonymous pipe는 양방향 통신을 지원한다.
- named pipe는 단방향 통신만 가능하다.
5. 동시성 지원
- anonymous pipe는 한 번에 두 개의 프로세스만 통신할 수 있다.
- named pipe는 여러 개의 프로세스가 동시에 통신할 수 있다.
따라서, anonymous pipe는 한 프로세스 내에서 부모-자식 간의 통신에 사용되고, named pipe는 다른 프로세스 간의 통신에 사용된다.
또한 named pipe는 파일 시스템에 등록되며, 파일처럼 접근할 수 있으므로 프로세스 간의 데이터 공유 등에 유용하다.
3. Message Queue
컨테이너 벨트와 유사한 구조로 큐에 담겨있는 데이터에 번호를 붙임으로써 여러개의 프로세스가 동시에 데이터를 쉽게 다룰 수 있다.
입출력 방식은 익명의 Pipe와 동일하지만 메모리를 사용한 Pipe이다. (Named Pipe가 데이터의 흐름이라면 메시지 큐는 메모리 공간)
FIFO 구조이며 구조체 기반으로 통신을 하고 msgtype에 따라 다른 구조체를 가져올 수 있다.
프로세스 간 다양한 통신을 할 때 사용할 수 있다.
커널에서 제공하는 Message Queue이기 때문에 enqueue에 제한이 존재한다.
4. Socket
네트워크 소켓 통신을 사용한 데이터 공유이다.
클라이언트와 서버가 소켓을 통해 통신하는 구조로, 원격에서 프로세스 간 데이터를 공유할 때 사용한다.
클라이언트 단에서는 connect를 통해 서버에 요청하고 서버단에서는 bind, listen, accept를 진행해 소켓 연결을 위한 준비를 한다.
연결이 수립된 후에는 socket에 send 함으로써 데이터를 주고 받으며 연결이 끝난 후에는 Socket을 반드시 close() 해줘야 한다.
전이중 (Full Duplex, 양방향) 통신이 가능하다.
중대형 어플리케이션에서 주로 사용한다.
메모리 공유 (Shared Memory)
프로세스끼리 특정 공통의 메모리 영역을 공유하며 상호간 통신하는 방법이다.
데이터 자체를 공유하도록 지원하며, 한 프로세스에서 변경한 메모리 공간의 내용을 다른 프로세스에서 접근할 수 있다.
공유 메모리는 커널에서 관리된다.
1. Shared Memory
일정한 크기의 메모리를 프로세스 간 공유하는 구조이며 공유 메모리는 커널에서 관리한다.
프로세스가 공유 메모리 할당을 커널에 요청하면 커널은 해당 프로세스에 메모리 공간을 할당해준다. 이후 어떤 프로세스건 해당 메모리 영역에 접근할 수 있다.
프로세스 간 읽기, 쓰기를 모두 필요로 할 때 사용한다.
대량의 정보를 다수의 프로세스에게 배포 가능하다.
중계자 없이 곧바로 메모리에 접근할 수 있기 때문에 모든 IPC 중에서 가장 빠르게 작동할 수 있다.
2. Memory Map
파일을 프로세스의 메모리에 일정 부분 매핑해서 사용한다.
공유 메모리와 마찬가지로 메모리를 공유한다는 공통점이 있다.
열린 파일을 메모리에 맵핑 시켜서 공유한다는 점이 차이점이다.
프로세스의 가상 메모리 주소 공간에 파일을 매핑한 뒤 가상 메모리 주소에 직접 접근한다.
운영체제에서 페이징 기법을 사용해 파일의 내용을 관리하며 페이지 크기에 따라 적절히 파일의 내용을 읽고 쓸 수 있다.
파일로 대용량 데이터를 공유해야 할 때 사용한다.
메모리 맵 파일은 크기를 바꿀 수 없으며 메모리 맵 파일을 사용하기 이전, 이후에만 파일의 크기를 바꿀 수 있다.
참고
'CS > 운영체제' 카테고리의 다른 글
[운영체제] DeadLock (데드락) (0) | 2022.04.04 |
---|---|
[운영체제] CPU Scheduling (0) | 2022.04.04 |
[운영체제] Process Management (0) | 2022.03.17 |
[운영체제] PCB(Process Control Block) & Context Switching (0) | 2022.03.17 |
[운영체제] System Call (0) | 2022.03.14 |
영차영차 성장 블로그
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!