본문 바로가기
시스템소프트웨어/실습

13) pipe

by LaTale 2017. 8. 31.

파이프를 이용한 동기화


리눅스에서는 프로그램에서 표준 출력장치로 출력한 내용을 다른 프로그램의 입력으로 전송할 수 있는데 이를 파이프라 한다.


popen()는 이 파이프기능을 이용해 다른 프로그램의 실행 결과를 읽어들이거나, 다른 프로그램의 표준 입력 장치로 출력할 수 있다.

1
2
3
#include <stdio.h>
FILE *popen(const char *command, const char *open_mode);
int pclose(FILE *stream_to_close);

command : 쉘에서 실행하는 명령어

open_mode : 출력방향

 - 'r' : 파이프를 통해서 입력받는다.

 - 'w' : 파이프를 통해서 출력한다.


위 예제에서 알 수 있듯이 popen()은 쉘인 sh를 먼저 호출하고 command를 인수로 전달하여 실행한다. 따라서 popen()을 호출할 때마다 쉘도 함께 실행되므로 비효율적이다.


pipe()는 쉘을 호출하는 overhead 없이 두 프로그램간의 데이터를 전달하는 수단을 제공한다. 원형은 다음과 같다.

1
2
#include <unistd.h>
int pipe(int file_descriptor[2]);

file_descriptor[0] : 수신 파일의 파일 디스크립터

file_descriptor[1] : 발신 파일의 파일 디스크립터

파일 디스크립터는 운영체제가 만든 파일 또는 소켓을 지칭하기 위해 부여한 숫자이다. 파일을 관리하기 위해 필요한 정보들을 가지고 있다.

반환)

성공시 0을 반환한다.

실패시 -1을 반환한다.




파이프 호출의 다음 단계는 하위 프로세스가 상위 프로세스와 다른 프로그램이 되도록 허용하는 것이다. 이 때 어려운 점은 새로운 실행 프로세스가 액세스 할 파일 디스크립터를 알아야 한다는 점이다. 이를 위해서는 data producer와 data consumer를 필요로 한다.

exec()를 이용해 수행할 수 있다.




pipe3.c의 19에서 sprintf()를 통해 file_pipes[0]의 내용을 buffer에 저장한다.

20을 통해서 buffer를 file_descriptor로 pipe4프로그램을 실행한다.

execl("전체 경로 이름","실행하고자 하는 프로그램 이름","실행하고자 하는 프로그램의 인수들")


pipe4.c의 10에서 sscanf()를 통해 argv[1](=buffer=file_descriptor)를 읽어서 실행한다.

_M#]


'시스템소프트웨어 > 실습' 카테고리의 다른 글

14) named pipe, socket  (0) 2017.09.04
12) semaphore  (0) 2017.06.06
11) shared memory  (0) 2017.06.01
10) thread attributes  (0) 2017.05.02
9) semaphore, mutexes  (0) 2017.04.06