IPC(InterProcess Communication)
스터디 Stacked-Book에서 실습과 그림으로 배우는 리눅스 구조 책을 참고하여 학습 후 정리한 글입니다.
IPC(InterProcess Communication)
- 프로세스가 실행되는 방식은 프로세스가
상호 독립적인 방식
(independent processes)과협력적인 방식
(cooperationg processes)으로 나뉜다. - 협력적인 방식일 경우 다른 프로세스와 서로 영향을 주고 받고 데이터를 공유해야한다.
- 이 때 프로세스간 데이터를 주고 받는 동작 또는 그에 대한 방법을 IPC라고 한다.
IPC의 종류
- shared memory
- message passing
shared memory
- 생산자와 소비자가 공유하는 어떤 메모리 영역을 의미한다.
- 버퍼를 이용하여 생산자는 버퍼를 채울 수 있고 소비자는 버퍼를 가져갈 수 있도록 한다.
- 버퍼는
unbounded buffer
와bounded buffer
로 나뉜다.- unbounded buffer : 버퍼 크기에 한계가 없다.
- bounded buffer : 고정 크기의 버퍼를 사용한다. 소비자는 버퍼가 비어있을 때 생산자는 버퍼가 가득 차있을 때 대기해야 한다.
- 예제
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
#### 버퍼 구조 #### #define BUFFER_SIZE 10 typedef struct { ... } item; item buffer[BUFFER_SIZE]; int in = 0; int out = 0; #### 생산자 코드 #### item next_produced; while (true) { /* next_produced에 아이템 생산 */ while ((in + 1) % BUFFER_SIZE) == out) { ; /* 아무 것도 안 함 */ } buffer[in] = next_produced; in = (in + 1) % BUFFER_SIZE; } #### 소비자 코드 #### item next_consumed; while (true) { while (in == out) { ; /* 아무 것도 안 함 */ } next_consumed = buffer[out]; out = (out + 1) % BUFFER_SIZE; /* next_consumed에 있는 아이템을 소비 */ }
shared memory 방식의 문제는 메모리 영역을 공유하게 될 때 메모리 영역에 명시적으로 액세스하거나 관리를 모두 프로그래머가 해야한다는 것이다. 공유가 많아질 수록 복잡해진다
message passing
- 메시지를 주고 받는 프로세스에 OS에서 수단을 제공하는 것이다.
- 즉 shared memory 관리를 OS가 하는 것이다.
- message passing은
send(message)
,receive(message)
두가지 연산을 제공한다. - 프로세스 간 통신을 위해서는 서로에게 반드시 메시지를 받아야한다 즉
communication link
가 있어야한다. link는 다양한 방법으로 구현될 수 있다.- 직 / 간접 통신
- 동기 / 비동기 통신
- 자동 / 명시적 버퍼링
IPC System의 예시
- Shared Memory : POSIX Shared Memory
- POSIX : Unix 계열에서 운영체제 표준화를 한 것이다.
- Message Passing : Pipes
- Unix에서 가장 기본적인 구현 방법 중 하나이다.
POSIX Shared memory
- POSIX 공유 메모리는 메모리에 매핑된 파일 (memory-mapped file)을 사용한다.
- 예제
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
int main() { /* 공유 메모리 개체의 크기 (바이트 단위) */ const int SIZE = 4096; /* 공유 메모리 개체의 이름 */ const char *name = "OS"; /* 공유 메모리에 쓸 문자열 */ const char* message_0 = "Hello"; const char* message_1 = "World!"; /* 공유 메모리 파일 설명자 */ int fd; /* 공유 메모리 개체를 가리키는 포인터 */ char *ptr; /* 공유 메모리 개체 생성 */ fd = shm open(name,O CREAT | O RDWR,0666); /* 공유 메모리 개체 크기 설정 */ ftruncate(fd, SIZE); ######## 생산자 코드 와 소비자 코드의 다른 부분 ######## ######## 생산자 코드 ######## /* 공유 메모리 개체를 메모리에 매핑 */ ptr = (char*) mmap(0, SIZE, PROT READ | PROT WRITE, MAP SHARED, fd, 0); /* 공유 메모리 개체에 쓰기 */ sprintf(ptr,"%s",message 0); ptr += strlen(message 0); sprintf(ptr,"%s",message 1); ptr += strlen(message 1); return 0; ########################## ######## 소비자 코드 ######## /* 공유 메모리 개체 메모리에 매핑 */ ptr = (char*) mmap(0, SIZE, PROT READ | PROT WRITE, MAP SHARED, fd, 0); /* 공유 메모리 개체로부터 읽기 */ printf("%s",(char *)ptr); /* 공유 메모리 개체 지우기 */ shm unlink(name); return 0; ########################## }
Pipes
- 두 개의 프로세스간 통신을 위한 수도관이라고 할 수 있다.
- 네가지 문제를 고려하여 구현한다.
- 양방향 통신을 허용할지 단방향 통신을 할지
- 양방향 통신이 가능하면 반이중 통신방식인지 전이중 통식방식인지
- 통신할 프로세스 간 관계(부모-자식 관계 같은)가 반드시 존재하는지
- 파이프가 다른 네트워크에서도 통신이 가능한지.
This post is licensed under CC BY 4.0 by the author.