프롬프트 메시지를 표시하고 사용자가 텍스트를 입력할 때까지 기다리는 프로그램이 있습니다.
$ program
Input a line of text: <aaaa>
Some more output.
$
이제 다음과 같이 FIFO를 통해 프로그래밍 방식으로 이 입력을 제공할 수 있기를 원합니다.
$ program < fifo
하지만 .stdout 에 입력을 제공할 때까지 프롬프트가 나타나지 않습니다 fifo
.
다음으로 나는 내 프로그램과 매우 간단하게 동등한 것을 시도했습니다. 그것은 다음과 같습니다:
$ echo aaaa < fifo
여기에서도 aaaa
입력이 제공될 때까지 나타나지 않습니다.fifo
질문:stdin
FIFO를 사용할 때 입력이 올 때까지 출력을 기다리게 하려면 어떻게 해야 합니까 ?stdout
답변1
FIFO는 셸에 의해 열리지만 다른 프로세스에서 쓰기 위해 FIFO를 열 때까지 해당 시작이 차단됩니다. 리디렉션이 처리되므로앞으로명령이 실행된 후에는 쉘 호출이 반환될 때까지 프로그램이 실행되지 않습니다 open()
. 이는 문서화된 동작입니다.C open()
라이브러리 함수(쉘에서 사용됨):
O_NONBLOCK
O_RDONLY
다음을 사용하거나 설정하여 FIFO를 켤 때O_WRONLY
:
O_NONBLOCK
설정된 경우open()
읽기 전용이 즉시 반환됩니다.open()
현재 읽기 위해 파일을 열어 놓은 프로세스가 없으면 쓰기 전용은 오류를 반환합니다.
O_NONBLOCK
지우 면open()
읽기 전용 호출 스레드는 스레드가 쓰기 위해 파일을 열 때까지 차단되어야 합니다.. 쓰기 전용은open()
스레드가 읽기 위해 파일을 열 때까지 호출 스레드를 차단해야 합니다.
따라서 쉘은 O_NONBLOCK
FIFO를 열 때 분명히 이를 사용하지 않습니다.
해결책:
cat fifo | program
cat
FIFO에서 파일 끝까지 읽은 후 종료합니다.tail -f fifo | program
tail
파일이 끝날 때까지 FIFO에서 읽은 다음 종료될 때까지 더 많은 콘텐츠를 기다리며 정지합니다.
이들 중 귀하의 상황에 가장 적합한 것은 부분적으로 상대방이 FIFO에 쓰는 내용과 작성 방법에 따라 달라집니다.
세 번째 해결책은 필요할 때 프로그램이 FIFO를 열도록 하는 것입니다.
~에 따르면기본원리부분sh
, 쉘은 표준 입력을 차단으로 설정해야 합니다. 왜냐하면...
쉘이 이 플래그를 재설정하지 않으면 아직 입력 데이터를 사용할 수 없기 때문에 즉시 종료되며 이는 파일 끝과 동일하게 처리됩니다.