- 11 프로세스간 통신 (Inter Process Communication)
- 11- 01 프로세스간 통신의 기본 개념
- 프로세스간 통신의 기본 이해
- 프로세스간 통신은 생각보다 어렵지 않은 개념이다. 프로세스 A가 프로세스 B에게 다음과 같이 말한다면 이 역시 프로세스간 통신의 규칙이 된다.
- 내게 빵이 하나 생기면 변수 bread의 값을 1로 변경하겠다. 그리고 그 빵을 먹어버리면 변수 breadᅟ의 값을 0으로 다시 변경하겠다. 그러니 너는 변수 bread의 값을 통해서 내 상태를 파악해라.
- 즉 프로세스 A는 변수 bread를 통해서 자신의 상태를 프로세스 B에게 말한 셈이고 프로세스 B는 변수 bread를 통해서 프로세스A가 한말을 들은 셈이다. 때문에 두 프로세스가 동시에 접근 가능한 메모리 공간만 있다면 , 이 공간을 통해서 얼마든지 데이터를 주고 받을수 있다. 하지만 이미 Chapter 10에서 공부했다시피 프로세스는 서로 완전히 별개의 메모리 구조를 지닌다 따라서 fork함수호출을 통해서 생성된자식 프로세스 조차 부모 프로세스와 메모리 공간을 조금도 공유하지 않는다. 그래서 프로세스간 통신은 별도로 마련된방법을 통해서만 이뤄질 수이 있다.
- 파이프(PIPE)기반 프로세스간 통신
- 다음 그림은 프로세스간 통신의 방법으로 사용되는 파이프 기법의 구조적 모델을 보이고있다.
- ( process A ) ---> PIPE -----> ProcessB
- 위 그림에서 보이듯이 두 프로세스간 통신을 위해서는 파이프라는 것을 생성해야 한다. 이파이프는 프로세스에 속하는 자원이 아니다 이는 소켓과 마찬가지로 운영체제에 속하는 자원이다(때문에 fork함수의 호출에 의한 복사 대상이 아니다)즉 운영체제가 마련해 주는 메모리 공간을 통해서 두 프로세스는 통신을 하게 된다. 그럼 먼저 파이프의 생성에 사용되는 함수를 소개하게싿.
- #include <unistd.h>
- int pipe(int filedes[2]);
- 성공시 0, 실패시 -1 반환
- filedes[0] : 파이프로부터데이터를 수신하는데 사용되는 파일 디스크립터가 저장된다. 즉 filedex[0]는 파이프의 출구가 된다.
- filedes[1] : 파이프로 데이터를 전송하는데 사용되는 파일 디스크립터가 저장된다. 즉 filedex[1]은 파이프의 입구가 된다.
- 길이가 2인 int형 배열의 주소 값을 인자로전달하면서 위의 함수를 호출하면 배열에는두 개의 파일 디스크립터가 담긴다. 그리고 이들 각각은 파이프의 출구와 입구로 사용된다. 결국 부모 프로세스가 위의 함수를 호출하면 파이프가 생성되고 파이프의 입구 및 출구에 해당 하는 파일디스크립터를 동시에 얻게 되는 것이다 따라서 부모 프로세스 혼자서 파이프 안으 데이터를 집어넣고 꺼내는것도 가능하다(이런놀이 누구나 한번쯤 하지않았는가?) 그런데 부모 프로세스의 목적은 자식 프로세스와의 데이터 송수신이니 입구 또는 출구에 해당하는 파일 디스크립터 중 하나를 자식 프로세스에게 전달해야 한다. 어떻게 하 이것이 가능하겠는가 ? 정답은 fork함수의호출에 있다. 그럼 예제를 통해서 이를 보자.
- pipe1.c
#include <stdio.h>
#include <unistd.h>
#define BUF_SIZE 30
int main(int argc, char *argv[])
{
int fds[2];
char str[] = "who are you?";
char buf[BUF_SIZE];
pid_t pid;
// pipe함수호출을 통해서 파이프를 생성하고 있다.
// 이로 인해서 배열 fds는 입출력을 위한 파일 디스크립터가 각각 저장된다.
pipe(fds);
// 이어서 fork함수를 호출하고 있다 따라서 자식 프로세스는
// 12행의 함수호출을 통해서 얻게 된 두 개의 파일 디스크립터를 함께 소유하게 된다.
// 주의하라! 파이프ㅏ 복사된 것이 아니라 파이프의 입출력에 사용되는 파일 디스크립터가 복사된 것이다.
// 이로써 부모와 자식 프로세스가 동시에 입출력 파일 디스크립터를 모두 소유하게 되었다.
pid = fork();
if( pid == 0 )
{
// 자식 프로세스는 아래의 실행을 통해서 파이프로 문자열을 전달한다.
write(fds[1], str, sizeof(str));
}
else
{
// 그리고 부모 프로세스는 아래의 실행을 통해서 파이프로부터 문자열을 수신한다.
read(fds[0], buf, BUF_SIZE);
puts(buf);
}
return 0;
}
- 위 예제에서 보인 통신 방법 및 경로를 그림으로 정리하면 다음 같다. 여기서 중요한 사실은 부모 자식 프로세스 모두 파이프의 입출력 경로에 접근이 가능하지만 자식은 입력 경로에만, 부모는 출력 경로에만 접근해서 통신을 했다는 점이다. 이로써 파이프의 기본 원리 및 통신 방법에 대한 설명이 모두 끝났다. 하지만 파이프의 활용에 있어서 주의야 할 내용이 조금 더 있기에 이를 양방향 통신을 예로 들면서 설명을 조금 더 하고자 한다.
'책 > 윤성우 TCPIP' 카테고리의 다른 글
11-01 프로세스간 통신의 기본 개념 (3) ~ 11-02 프로세스간 통신의 적용 (0) | 2020.12.26 |
---|---|
11-01 프로세스간 통신의 기본 개념 (2) (0) | 2020.12.25 |
10-05 TCP의 입출력 루틴(Routine)분할 (2) (0) | 2020.12.23 |
10-05 TCP의 입출력 루틴(Routine)분할 (0) | 2020.12.22 |
10-04 멀티태스킹 기반의 다중접속 서버(2) (0) | 2020.12.21 |