18.파이프

#.파이프

파이프는 두 프로세스 사이에서 한 방향으로 통신할 수 있도록 지원한다.

 

종류

*이름있는 파이프

*이름없는 파이프

 

#.이름없는 파이프

부모-자식 프로세스 간에 통신할 수 있게 해준다. 부모 프로세스에서 fork 함수를 통해 자식 프로세스를 생성하고, 부모 프로세스와 자식 프로세스 간에 통신하는 것이다. (자식 프로세스가 출력한 내용을 부모 프로세스에서 읽을 것인지 둘 중 한 방향을 선택해야 한다.)

 

*간단한 파이프 생성

FILE *popen(const char *command, const char *mode);

int pclose(FILE *stream);

 

*복잡한 파이프 생성

int pipe(int fildes[2]);

 

#.파이프 생성: pipen(3)

#include <stdio.h>

FILE *popen(const char *command, const char *mode);

popen 함수는 내부적으로 fork 함수를 실행해 자식 프로세스를 만들고 command에서 지정한 명령을 exec 함수로 실행해 자식 프로세스가 수행하도록 한다. 리턴값은 파일 포인터이다. 파일 입출력 함수에서 이 파일 포인터를 사용하면 파이프를 읽거나 쓸 수 있다. popen 함수는 파이프 생성에 실패하면 널 포인터를 리턴한다.

 

#.파이프 닫기: pclose(3)

#include <stdio.h>

int pclose(FILE *stream);

pclose 함수는 관련된 waitpid 함수를 수행하며 자식 프로세스들이 종료하기를 기다렸다가 리턴한다. 리턴값은 자식 프로세스의 종료 상태. 닫는데 실패하면 -1을 리턴한다.

 

*popen 함수를 사용해 파이프를 생성하는 일은 쉘을 실행해야 하므로 비효율적이고 주고받을 수 있는 데이터도 제한적이다. pipe 함수를 사용하면 더 효율적으로 생성할 수 있다. 

 

#.파이프 만들기: pipe(2)

#include <unistd.h>

int pipe(int fildes[2]);

 

pipe 함수는 인자로 크기가 2인 정수형 배열을 받는다. fildes[0]은 읽기 전용으로 열고, fildes[1]은 쓰기 전용으로 연다. pipe 함수는 파이프를 생성하는 데 성공하면 0을, 실패하면 -1을 리턴한다. 

 

#.pipe 함수로 통신하는 과정

파이프를 생성하고나면 일반적으로 fork 함수를 호출해 자식 프로세스를 생성한다. 자식 프로세스는 부모 프로세스가 pipe 함수로 생성한 파일 기술자들도 복사한다. 이 파이프를 이용해 한 프로세스에서는 쓰기를 수행하고, 다른 프로세스에서는 읽기를 수행하면 통신이 이루어진다.

 

 

 

 

 

#.양방향 파이프의 활용

 

#.이름 있는 파이프 : FIFO

이름 없는 파이프는 부모-자식 프로세스 간에만 통신을 할 수 있다는 단점이 있다.

독립적인 프로세스들이 파이프를 이용하려면 파일처럼 이름이 있어야한다.

이름이 붙은 파이프로 모든 프로세스가 이 파이프명을 이용해 통신할 수 있다.

 

 

*FIFO 생성 명령

mknod name p

mkfifo [-m mode] path...

 

*FIFO 생성 함수

int mknod(const char *path, mode_t mode, dev_t dev);

mknod 함수는 첫번째 인자인 path로 지정한 경로에 특수 파일을 생성한다. 

두번째 인자인 mode에는 특수 파일의 종류와 접근 권한을 지정한다.

(성공하면 0을, 실패하면 -1)

 

#.특수파일 종류

  • S_FIFO: FIFO 특수 파일

  • S_IFCHR: 문자 장치 특수 파일

  • S_IFDIR: 디렉토리

  • S_IFBLK: 블록 장치 특수 파일

  • S_IFREG: 일반 파일

int mkfifo(const char *path, mode_t mode);

 

#.FIFO 데이터 주고받기

FIFO 파일을 생성하면 저수준 파일 입출력 함수로 이 파일을 읽거나 쓸수 있다.

FIFO도 파이프와 마찬가지로 단방향 통신이기 때문에, FIFO 파일을 읽거나 쓰기 위해 열 경우 반드시 읽기 전용(O_RDONLY)이나 쓰기 전용(O_WRONLY)으로만 열어야 한다. 

 


 

#.popen 함수(쓰기 전용 모드)를 사용해 파이프를 생성 예제

결과

 

 

#.자식 프로세스가 파이프에 기록한 데이터를 부모 프로세스가 읽어서 처리 예제

결과

 

#.부모 프로세스가 파이프에 출력한 문자열을 자식 프로세스가 파이프에서 읽어들이는 예제

결과

 

 

#.부모 프로세스가 파이프에 출력한 문자열을 자식 프로세스가 파이프에서 읽어들이는 예제2

결과

 

#.파이프 두개를 생성해 부모 프로세스와 자식 프로세스 간에 양방향 통신을 수행하는 예제

결과

 

#.mknod와  mkfifo 함수를 사용해 FIFO 파일을 생성하는 예제

결과

 

#.서버 프로세스에서 보낸 문자열을 클라이언트 프로세스가 받아서 출력하는 예제

-서버

-클라이언트

결과

 

 

 

 

 

참고: 유닉스 프로그래밍(한빛 미디어)