왜 배관 입력은 zenity에 적합하지만,

왜 배관 입력은 zenity에 적합하지만,

내 질문은 zenity --text예제의 매개변수만큼 간단합니다. 하지만 리디렉션으로 인해 CPU 사용량이 100% 발생하는 원인은 무엇입니까?
...(그런데 이 특별한 사용법은 <실제로 이라고 합니다 redirection. 대신에 방향을 만드는 것처럼 보입니다.~에 대한- 감독)..

echo "Peacocks talking of the colour grey."> test
cat test | zenity --text='This does NOT hog the CPU'   --list --column='#' --width=450 
<test      zenity --text='This hogs 100% of CPU usage' --list --column='#' --width=450
 

사용하게 되어 기쁩니다 cat test |(이 경우에는 쓸모가 없기 때문입니다. 효과가 있고 |어떤 면에서는 차이가 있지만 다시 추적할 수는 없습니다...

분명히 말하면 <test둘 다 cat test |유효합니다. 두 경우 모두 zenity 대화 상자가 나타나고 완벽하게 작동하지만 <test해당 버전의 대화 상자가 열려 있는 한 단일 "코어" VM %에서 100% CPU(1개 코어)...94를 사용합니다. .

답변1

이것은 zenity의 버그처럼 보입니다. 이 도구를 사용하여 무슨 일이 일어나고 있는지 확인할 수 있습니다. strace(이 게시물에서 추적 라인을 더 쉽게 읽을 수 있도록 래핑했습니다.)

파이프 버전의 경우 strace의 이 줄은 cat파이프가 닫힐 때(종료로 인해) 무슨 일이 일어나는지 보여줍니다.

poll([{fd=4, events=POLLIN}, {fd=3, events=POLLIN}, {fd=0, events=POLLIN}], \
     3, 0) = 1 ([{fd=0, revents=POLLIN|POLLHUP}])

마지막 부분은 - fd=0, revents=POLLIN|POLLHUP구체적으로 POLLHUP- zenity에게 표준 입력이 중단되었음을 알려줍니다(파이프 작성자가 사라졌습니다). Zenity는 이를 올바르게 처리하고 나중에 fd 0을 닫습니다.

파일은 이벤트를 받지 않습니다 POLLHUP. 대신 read(2)결과가 0이면 EOF를 의미합니다. 이는 zenity의 다른 코드 경로입니다. fd 0을 다시 폴링하고 다음 결과를 얻습니다.

poll([{fd=4, events=POLLIN}, {fd=3, events=POLLIN}, {fd=0, events=POLLIN}],\
     3, 0) = 1 ([{fd=0, revents=POLLIN}])
read(0, "", 1024)       = 0

이것이 끝입니다. 0 읽기로 인해 zenity가 fd 0을 닫아야 합니다. 그러나 그것은 진실이 아니다. zenity가 fd 0을 계속 폴링하기 때문에 위의 strace 출력은 계속 반복됩니다. fd 0이 닫힐 때까지 항상 읽을 준비가 되어 있습니다. EOF 결과를 얻으려면 파일 설명자를 읽어야 하기 때문에 EOF의 파일 설명자가 작동하는 방식이기 때문입니다.

zenity 는 stdin의 EOF에 poll(2)제대로 응답하지 않기 때문에 . 몇 번이고, 몇 번이고...read(2)pollread

답변2

이 시도:

zenity --text='This does NOT hog the CPU' --list --column='#' --width=450 <(cat test)

관련 정보