Closed youngreal closed 2 years ago
프로세스는 다른프로세스들과 데이터를공유하지않는 프로세스와, 협력하는 프로세스가 있는데 협력적 프로세스들끼리 데이터를 교환할수있는 통신수단이 필요하며 그 기법을 IPC(프로세스간 통신) 이라고 합니다. 클라이언트가 데이터를 요청하고 서버는 응답하는것도 IPC의 예입니다
통신하는 프로세스들이 공유 메모리영역을 구축하여 공유영역에 프로세스들이 읽고쓰며 정보를 교환할수있는 공유메모리 방식과 동일한 주소공간을 공유하지않고도 프로세스들 사이에 교환되는 메시지를 통하여 통신이 이루어지는 메시지 전달 시스템이 있습니다 이외에도 소켓,파이프를 이용한 통신도 IPC의 사례입니다
두 프로세스가 통신할수있게 하는 전달자 입니다. 파이프를 구현하기위해선 단방향, 양방향 통신인지 양방향 통신이라면 반이중방식(한번에 한방향 전송) 인지, 전이중방식(동시에 양방향 전송가능) 인지 고려해야합니다
예제
#### 버퍼 구조 ####
#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 방식의 문제는 메모리 영역을 공유하게 될 때 메모리 영역에 명시적으로 액세스하거나 관리를 모두 프로그래머가 해야한다는 것이다. 공유가 많아질 수록 복잡해진다.
예제
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;
##########################
}
IPC는 프로세스 간 통신이며, 프로세스들끼리 서로 데이터를 주고 받는 행위 그에 대한 방법을 뜻합니다.
두 개 모두 커널에서 관리가 됩니다.
두 프로세스가 통신할수있게 하는 전달자역할을 하는 것을 파이프라고 합니다.
- IPC 통신과는 달리 한 방향으로만 통신이 가능합니다.
- 파이프 자체는 fork 함수에 의해 복사되지가 않는다고 합니다.
단 양방향 통신을 구현하게 될 경우 위처럼 파이프를 두 개를 생성해서 구현을 하게 됩니다.
이때 양방향 통신을할때 반이중을 할지 전이중 통신방식으로 구현할지 고민을 해봐야합니다.
기본적으로 프로세스는 자신에게 할당된 메모리에만 접근 가능하기 때문에 협동 프로세스들 간에는 통신 기법이 필요하다.
공유 메모리
공유 메모리는 두 개의 프로세스 안에 서로 공유할 수 있는 메모리이다. 시스템 호출로 등록되어진 메모리에 한에서 다른 프로세스들이 데이터를 읽을 수 있다. 데이터를 만들 때는 커널의 도움이 필요하지만 읽을 때는 사용자의 모드로 읽을 수 있다.
공유 메모리 시스템
서로 통신하려는 프로세스 간 공유 메모리 영역을 구축한다. 각 프로세스는 이 영역을 자신의 주소 공간에 추가하고 접근한다.
접근 방법
메시지 전달
필요한 데이터를 직접적으로 가져오는 게 아닌 커널을 통해 메시지를 주고 받는다.
신호
한 프로세스에게 어떤 상황의 발생을 비동기적으로 알리는 방법이다. 한 프로세스가 다른 프로세스에게 알리거나 커널이 특정 프로세스에게 알리게 된다. 현재 프로세스 내외부에서 예상치 못하게 발생하는 비동기적 사건을 처리하기 위한 방법이다. 신호의 전달은 커널에 의해 이뤄진다.
💡 가장 오래된 IPC 방법이다.
파이프
프로세스간에 데이터를 전달하는 방법이다. 전송되는 데이터의 읽기 쓰기 위치를 임의로 변경할 수 없다. 그리고 순차적으로 읽고 사용해야 한다. 시스템 호출을 통해 커널 공간에 생성된 파이프를 통해 전달한다.