명명된 파이프가 있고 fifo
두 개의 서로 다른 쉘에서 읽고 쓰고 있다고 가정합니다. 다음 두 가지 예를 고려하십시오.
shell 1$ echo foo > fifo
<hangs>
shell 2$ cat fifo
foo
shell 1$ echo bar > fifo
<hangs>
shell 1$ cat > fifo
<typing> foo
<hangs>
shell 2$ cat fifo
foo
^C
shell 1$
<typing> bar
<exits>
이 예에서 무슨 일이 일어나고 있는지, 특히 파이프에 "bar"를 쓰려고 하면 첫 번째 예에서는 차단 호출이 발생하고 두 번째 예에서는 SIGPIPE가 트리거되는 이유를 이해할 수 없습니다.
나는 첫 번째 경우 두 개의 개별 프로세스가 파이프에 쓰기 때문에 두 번 열리는 반면 두 번째 경우에는 한 번만 열리고 단일 프로세스에 의해 두 번 기록되고 프로세스가 파이프에서 읽기로 시작된다는 것을 이해합니다. 이 시간 동안. 내가 이해하지 못하는 것은 이것이 행동에 어떤 영향을 미치는가입니다 write
.
매뉴얼 pipe(7)
페이지에는 다음과 같이 명시되어 있습니다.
파이프의 읽기 끝을 참조하는 모든 파일 설명자가 닫힌 경우쓰다(2) 호출 프로세스에 대해 SIGPIPE 신호가 생성됩니다.
이 조건은 나에게 명확하게 들리지 않습니다. ㅏ폐쇄파일 설명자는 더 이상 파일 설명자가 아닙니다. 그렇죠? 어떻게 말해야 할까요?"파이프의 읽기 끝이 닫혔습니다." 달리 "파이프의 판독 끝이 열려 있지 않습니다."?
내 질문이 충분히 명확해지기를 바랍니다. 그런데, open
, , 연산과 관련된 Unix 파이프 기능에 대해 자세히 살펴보도록 제안해 주시면 감사하겠습니다.close
read
write
답변1
귀하의 예에서는 a fifo
대신 a 를 사용하므로 pipe
다음이 적용됩니다.fifo(7)
.pipe(7)
또한 다음과 같이 말했습니다.
FIFO(선입선출의 약어)는 파일 시스템(mkfifo(3)를 사용하여 생성됨)에 이름을 가지며 open(2)을 사용하여 열립니다. 파일 권한이 허용하는 경우 모든 프로세스에서 FIFO를 열 수 있습니다. 읽기 측을 열려면 O_RDONLY 플래그를 사용하고, 쓰기 측을 열려면 O_WRONLY 플래그를 사용하십시오. 자세한 내용은 fifo(7)을 참조하세요. 참고: FIFO에는 파일 시스템에 경로 이름이 있지만 FIFO의 I/O에는 기본 장치(있는 경우)에 대한 작업이 포함되지 않습니다.
파이프 및 FIFO의 I/O
파이프와 FIFO의 유일한 차이점은 생성 및 여는 방식입니다. 이러한 작업이 완료되면 파이프와 FIFO의 I/O는 정확히 동일한 의미를 갖게 됩니다.
그럼 이제부터fifo(7)
:
커널은 하나 이상의 프로세스에서 연 각 FIFO 특수 파일에 대한 파이프 개체를 유지 관리합니다. 데이터를 전송하려면 먼저 FIFO(읽기 및 쓰기)의 양쪽을 열어야 합니다. 일반적으로 다른 쪽 끝도 열릴 때까지 FIFO 블록을 엽니다.
따라서 쓰기 블록은 양쪽 끝(여기서는 최소한 하나의 판독기와 하나의 기록기를 의미함)이 열리기 전에 뒤따릅니다 fifo(7)
. 양쪽 끝이 열리고 읽기 끝이 닫힌 후 쓰기는 요청에 따라 SIGPIPE를 생성합니다 pipe(7)
.
파이프 사용(fifo 아님)의 예는 다음을 참조하세요.예제 섹션pipe(2)
: Pipe()(pipe()가 실제로 개방형 파이프 쌍을 생성하므로 open() 없음), close(), read(), write() 및 fork()(파이프를 사용할 때 거의 항상 fork()가 포함됩니다. ))).
fifo에 쓰는 동안 죽고 싶지 않다면 자신의 C 코드에서 SIGPIPE를 처리하는 가장 쉬운 방법은 signal(SIGPIPE, SIG_IGN);
각 write() 후에 errno를 확인하여 호출하고 처리하는 것입니다.EPIPE
답변2
읽기 프로세스 없이 파이프나 FIFO에 쓰는 것은 오류 조건으로 간주되며 SIGPIPE 신호를 생성하고 신호가 처리되거나 차단되면 오류 코드 EPIPE와 함께 실패합니다.