이러한 특징은 유닉스 명령어 라인(유닉스 쉘)에서 조차 폭넓게 사용된다.
ls | sort | lp위의 예는 ls의 출력을 sort의 입력으로 하고 sort의 출력을 lp의 입력으로 사용하기 위해 파이프(pipe)를 이용하였다. 자료는 파이프라인을 통해 왼쪽에서 오른쪽으로 이동하듯이, 반이중 파이프를 통해 움직인다.
우리들이 쉘 스크립트 프로그래밍에서 파이프를 아주 세심하게 사용한다해도, 커널 레벨에서 일어나는 일에 대해서는 생각하지 않고 사용한다.
프로세스가 파이프를 만들 때, 커널은 파이프에 의해 사용될 두개의 파일 식별자(descriptor)를 준비한다. 한개의 식별자(descriptor)는 파이프(Write)의 입력 통로로 사용되고 다른 하나는 파이프(Read)로 부터 자료를 얻는데 사용된다. 이런 점에서 생성하는 프로세스는 자기자신과의 통신에만 파이프를 사용함으로 파이프는 거의 실질적으로 사용되지 않는다. 파이프가 만들어진 이후의 프로세스와 커널의 개념작용에 주의하라.
- 애석하게도 원문에서 다이어그램 그림이 빠져있음
위의 다이어그램으로 부터 식별자들이 서로 어떻게 연결되는지 쉽게 알 수 있다.
프로세스가 파이프(fd0)를 통해 자료를 보낸다면, fd1로 부터 자료를 얻을 수 (읽을 수) 있는
능력을 가지고 있다. 그렇지만 위의 극히 간단한 그림의 실재물은 매우 크다.
파이프가 처음에 프로세스와 자신을 연결하는 동안, 파이프를 통해 여행 중인 자료는 커널을
통해 움직인다. 특히 리눅스에서 파이프는 실제로 내부적으로 유효한 inode를 가지고 있음을
의미한다. 물론, 이 inode는 커널안에 존재하고 물리적인 파일 시스템에는 아무런 영향을
끼치지 않는다. 이러한 특징은 우리가 수동 I/O 문(handy I/O doors)을 열 수 있게 한다.
이러한 점에서 파이프는 명백히 쓸모없다. 결국, 우리가 오직 우리 자신에게 이야기하고자 한다면 왜 파이프 생성의 어려움을 가지고 가야만 하는가? 생성하는(creating) 프로세스는 전통적으로 자식 프로세스(child process)를 생성(fork)한다. 자식 프로세스는 부모로 부터 열려진 파일 식별자도 상속받았으므로 우리는 부모와 자식간의 멀티프로세스 통신을 위한 기초를 가지고 있다. 우리의 간단한 그림 수정본에 주의하라.
위와 같이 우리는 두 프로세스가 파이프 라인을 구성하는 파일 식별자에 접근할 수 있음을 볼 수 있다. 이번에는 중요한 결정을 내려야 한다. 어떤 방향으로 자료가 이동하기를 원하는가? 자식 프로세스가 부모에게 정보를 보낼 것인가 아니면 그 반대인가? 두 프로세스는 이러한 문제에 대해 상호 동의하고 있고 관계되어 있지 않은 파이프의 끝은 닫는다. 토론의 목적을 위해, 자식 프로세스가 어떤 작업을 수행하고 파이프를 통해 부모에게 정보를 전하는지를 살펴보자. 우리의 새롭게 고안된 그림은 다음과 같이 나타난다.:
현재 파이프라인의 구성은 완벽하다! 남아있는 일은 파이프의 사용뿐이다. 파이프에 직접적으로 접근하기 위해, 하위 레벨의 파일 I/O를 위해 사용되는 같은 기능의 시스템 호출을 사용할 수 있다. (파이프가 실제 내부적으로 유효한 inode로 표현됨을 기억하라)
파이프로 자료를 보내기 위해, 우리는 write() 시스템 호출을 사용하고 파이프로 부터 자료를 조회하기 위해 read()라는 시스템 호출을 사용한다. 하위 레벨의 파일 I/O 시스템 호출은 파일 식별자를 가지고 작업함을 기억하라! 어쨌든, 파이프에서 식별자를 가지고 작업하지 않는 lseek()와 같은 시스템 호출들을 기억하라.
Copyright (c) 1996,1997 by Euibeom.Hwang & SangEun.Oh All Rights Reserved
Email To:Webmaster ,
Another address
LAST UPDATE Nov 14,1997
Created Nov 14,1997