![파이프된 쉘 프로그램은 출력/입력 속도의 균형을 어떻게 유지합니까? [복사]](https://linux55.com/image/26716/%ED%8C%8C%EC%9D%B4%ED%94%84%EB%90%9C%20%EC%89%98%20%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%A8%EC%9D%80%20%EC%B6%9C%EB%A0%A5%2F%EC%9E%85%EB%A0%A5%20%EC%86%8D%EB%8F%84%EC%9D%98%20%EA%B7%A0%ED%98%95%EC%9D%84%20%EC%96%B4%EB%96%BB%EA%B2%8C%20%EC%9C%A0%EC%A7%80%ED%95%A9%EB%8B%88%EA%B9%8C%3F%20%5B%EB%B3%B5%EC%82%AC%5D.png)
중복 가능성:
while 루프를 배싱하고 파이프에서 읽습니다.
저는 웹 프로그래밍에 대한 배경 지식이 있고 로컬 셸의 기능을 사용하는 데 관심이 있습니다. 내가 아는 한, 프로그램이 파일을 읽을 때 필요한 속도로 읽을 수 있습니다. 그런데 프로그램이 파이프를 통해 다른 프로그램으로부터 입력을 받고 이를 실시간으로 처리할 수 없는 경우 어떻게 작동하는지 궁금합니다.
좋은 예는 비디오 인코딩입니다. 디코더가 비디오 파일을 가리키고 그 출력이 인코더의 입력으로 파이프된다고 가정해 보겠습니다. 디코딩된 영상의 전체 크기가 메모리 + 스왑 공간을 초과하므로 완전히 버퍼링할 수 있는 방법은 없을 것 같습니다. stdin 및 stdout에 대한 읽기 및 쓰기 호출을 찾았지만 이 예제의 인코더가 모든 데이터를 동시에 처리할 수 없을 때 실제로 어떤 일이 발생하는지 알고 싶습니다. 어떻게든 디코더에 필요한 속도를 알려주나요? 그러한 신호에 대해 디코더 프로그램을 특별히 준비하고 그에 따라 처리 속도를 수정해야 합니까? 그렇지 않다면 결국 균형을 맞추는 방법은 무엇입니까?
답변1
작성기가 파이프에 쓰고 파이프가 가득 차면(크기는 몇 킬로바이트로 제한됨) 판독기 중 하나가 일부 공간을 확보할 때까지 해당 프로세스가 차단됩니다. 마찬가지로 리더가 파이프에서 데이터를 읽으면 해당 프로세스는 무언가가 있을 때까지 차단됩니다.
프로그래머가 이러한 읽기 및 쓰기를 대기열에 추가하는 데 사용할 수 있는 비동기식 쓰기 및 읽기도 있습니다.
나는 독서를 적극 권장합니다Beej의 안내, Beej에서 시작Unix 프로세스 간 통신 가이드
두 개의 매개변수를 사용하여 이를 호출합니다. 첫 번째는 작성자의 수면 시간이고 두 번째는 독자의 수면 시간입니다. args를 사용해보십시오 0 3
.3 0
#!/bin/sh
write_sleep=$1
read_sleep=$2
writer(){
echo writing output >&2
echo hi
sleep $write_sleep
echo writing output >&2
echo hi
sleep $write_sleep
echo writing output >&2
echo hi
sleep $write_sleep
}
reader(){
while true; do
echo getting input >&2
read input
[ $input ] || { echo input is empty >&2 && break; }
echo $input
sleep $read_sleep
done
}
writer | reader
답변2
파이프는 프로그래밍 수준의 일반적인 UNIX 설명자입니다. 파이프를 통해 통신하기 위해 두 프로그램을 설정할 때 가장 먼저 보게 되는 것은 상호 작용하는 표준 출력 및 표준 입력 설명자입니다. 왜냐하면 쉘이 실제로 그렇게 설정하기 때문입니다. 이러한 방식으로 설정하면 이러한 설명자는 몇 가지 특별한 특성을 가지지만 프로세스는 다른 파일 설명자와 마찬가지로 설명자와 상호 작용합니다(이것이 전체 UNIX 철학입니다).
기본적으로 쓰기 프로세스는 파이프에 얼마든지 데이터를 쓸 수 있지만, 파이프에는 최대 저장 한도(버퍼)가 있으므로 파이프가 가득 차면 차단될 수도 있고, 요청이 " Try "로 응답될 수도 있습니다. 작성자가 차단되는 것을 원하지 않으니 나중에 다시 시도하세요."
대신, 독자는 원하는 만큼 읽을 수 있지만 파이프가 비어 있으면 차단될 수도 있습니다(또는 "나중에 다시 시도하세요"라고 응답할 수도 있음).