[리눅스 프로그래밍] - (IPC) PIPE 다루기

Yoon Yeoung-jin·2022년 7월 2일
0

Linux

목록 보기
7/13

01. IPC Programming Using PIPE

[그림 출처: https://doitnow-man.tistory.com/110]

  • IPC 프로그래밍 기법 중 하나이다.
  • 익명의 PIPE를 통해서 동일한 PPID를 가진 프로세스들 간에 단방향 통신을 지원한다.
    • 단방향 통신을 지원하기 때문에 fork()를 사용하여 자식 프로세스를 열 경우 파일 디스크립터를 close 해주는 코드가 필요하다.
  • 구조는 FIFO(First In First Out) 구조를 가지고 있다.
  • related process 간에 사용 가능하다. (ex. fork())

02. 사용 API

  • 헤더 파일
    • unistd.h
  • 함수
    • int pipe(int pipefd[2])
      파라미터: 
      	- pipefd[2]:생성될 pipe fd[2]를 저장할 버퍼
      		- pipefd[0]: reader-side fd
      		- pipefd[1]: writer-side fd 
      RETURN
      	- 성공: 0
      	- 실패: 1

03. 참고 사항

  • pipe가 full일 때 write를 시도하면 blocking
  • pipe가 비어있을 때 read를 시도하면 blocking
  • write size가 PIPE_BUF보다 작으면 atomix, 크면 쪼개져서 저장될 수 있음.
    • 쪼개져서 저장될때 중간에 다른 데이터가 들어올 수 있다.
    • Linux PIPE_BUF: 4KB

04. 예제 코드

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

#include<sys/types.h>

#define MAX_BUF_LEN 1028

static void recv_data(int fd)
{
    char buf[MAX_BUF_LEN];
    memset((void *)buf, 0, sizeof(buf));
    if(read(fd, (void *)buf, sizeof(buf)) == -1){
        perror("read()");
        return ;
    }
    printf("[Recv Data] - [Child] pid: %u, %s\n",getpid(),buf);

}

static void send_data(int fd)
{
    char buf[MAX_BUF_LEN];

    memset((void *)buf, 0, sizeof(buf));
    snprintf(buf, sizeof(buf), "msg: %s", "Hello world");
    printf("[Send Data] - [PARENT] pid: %u, %s\n",getpid(),buf);
    if(write(fd, buf, sizeof(buf)) == -1){
        perror("write()");
        return ;
    }
}

int main(int argc, char **argv)
{
    pid_t pid;
    int pipefd[2] = {0,};
    if(pipe(pipefd) == -1){
        perror("pipe()");
        return -1;
    }
    pid = fork();
    if(pid == 0){
        /* parent process */
        close(pipefd[0]);
        send_data(pipefd[1]);
        close(pipefd[1]);
    } else if(pid > 0) {
        /* child process */
        close(pipefd[1]);
        recv_data(pipefd[0]);
        close(pipefd[0]);
    } else {
        perror("fork()");
        return -1;
    }

    return 0;   
}
profile
신기한건 다 해보는 사람

0개의 댓글