C언어 파이프를 이용한 IPC 함수 pipe()

2020. 3. 16. 08:00 컴퓨터/프로그래밍

C함수 파이프를 이용한 IPC pipe()

프로세스 간의 통신(IPC)에서 사용하는 파이프를 생성합니다.

  • 헤더: unistd.h
  • 형태: int pipe(int filedes[2])
  • 인수: int filedes[2] 파이프의 입출력 디스크립터
  • 반환: 0 == 성공, -1 == 실패

pipe()에서 생성하는 파이프는 프로세스 안에 생성되는 것이 아니라 커널에 생성되며 프로세스에는 다만 파이프를 이용할 수 있는 파일 디스크립터만 제공됩니다. 그러므로 하나의 프로세스에서 파이프를 생성했다고 해도 다른 프로세스에서 그 디스크립터를 사용할 수 있다면, 그 디스크립터를 이용하여 서로 통신할 수 있습니다.

그러나 pipe()에서 생성한 파이프의 문제점은 입출력 방향이 결정되어 있다는 점이니다. pipe()를 실행하면 파이프를 이용할 수 있는 2개의 파일 디스크립터가 구해집니다.

int pipe(int filedes[2]);

2개의 파일 디스크립터 중,

  • filedes[0] 은 파이프의 읽기 전용 디스크립터입니다.
  • filedes[1] 은 파이프의 쓰기 전용 디스크립터입니다.

그림의 첫 번째처럼 프로세스에 따라 읽기와 쓰기 디스크립터가 서로 다르다면 문제가 없겠지만 모두 같은 출구와 입구를 사용하고 있기 때문에 만일 프로세스끼리 쌍방향 통신을 해야 한다면 아래와 같은 문제가 발생합니다.

이렇게 사용한다고 해도 문제점이 또 있습니다. 파이프의 디스크립터를 사용해야 하므로 부보와 자식 프로세스 사이에만 사용할 수 있습니다. 서로 다른 프로그램에서 실행된 프로세스 끼리 통신하려면 FIFO를 이용해야 합니다.

예제

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#define  BUFF_SIZE   1024

int main()
{
   int   pipes_parent[2];
   int   pipes_child[2];
   char  buff[BUFF_SIZE];
   int   counter  = 0;
   pid_t pid;


   if ( -1 == pipe( pipes_parent)){
      perror( "파이프 생성 실패");
      exit( 1);
   }

   if ( -1 == pipe( pipes_child)){
      perror( "파이프 생성 실패");
      exit( 1);
   }
   pid   = fork();

   switch( pid){
   case -1  :
      printf( "자식 프로세스 생성 실패\n");
      return -1;
   case 0   :          // 자식 프로세스입니다.
      while( 1 ){
         sprintf( buff, "자식 메시지: %d", counter++);
         write( pipes_child[1], buff, strlen( buff));
         memset( buff, 0, BUFF_SIZE);
         read( pipes_parent[0], buff, BUFF_SIZE);
         printf( "자식 프로세스: %s\n", buff);
         sleep(1);
      }
   default  :          // 부모 프로세스입니다.    
      while( 1){
         sprintf( buff, "부모 메시지: %d", counter--);
         write( pipes_parent[1], buff, strlen( buff));
         memset( buff, 0, BUFF_SIZE);
         read( pipes_child[0], buff, BUFF_SIZE);
         printf( "부모 프로세스: %s\n", buff);
         sleep(1);
      }
   }
}

실행 결과

]$ ./a.out
자식 프로세스: 부모 메시지: 0
부모 프로세스: 자식 메시지: 0
부모 프로세스: 자식 메시지: 1
자식 프로세스: 부모 메시지: -1
자식 프로세스: 부모 메시지: -2
부모 프로세스: 자식 메시지: 2
부모 프로세스: 자식 메시지: 3
자식 프로세스: 부모 메시지: -3
부모 프로세스: 자식 메시지: 4
자식 프로세스: 부모 메시지: -4
자식 프로세스: 부모 메시지: -5
부모 프로세스: 자식 메시지: 5
자식 프로세스: 부모 메시지: -6
^C
]$
이 댓글을 비밀 댓글로