내가 읽고 있어요리눅스 프로그래밍 인터페이스.
~에서63.2.3 파일 디스크립터는 언제 준비되나요?, 그것은 말한다 :
select()
파일 설명자를 올바르게 사용하려면poll()
파일 설명자가 준비 상태를 나타내는 조건을 이해해야 합니다. SUSv3에서는O_NONBLOCK
I/O 함수에 대한 호출이 차단되지 않으면 파일 설명자(삭제 포함)가 준비된 것으로 간주됩니다.함수가 실제로 데이터를 전송하는지 여부에 관계없이. 기울임꼴 강조: I/O 작업이 데이터를 성공적으로 전송할지 여부가 아니라 차단되지 않을지 여부를select()
나타냅니다 .poll()
이를 염두에 두고 이러한 시스템 호출이 다양한 유형의 파일 설명자에서 어떻게 작동하는지 고려해 보겠습니다. 이 정보는 두 개의 열이 있는 테이블에 표시됩니다.
- 이
select()
열은 파일 설명자가 읽기 가능(r), 쓰기 가능(w)으로 표시되었는지 또는 예외 조건(x)이 있는지 여부를 나타냅니다.....
파이프 및 FIFO
표 63-4에는 파이프 또는 FIFO의 읽기 측에 대한 세부 정보가 요약되어 있습니다. 이
Data in pipe?
열은 파이프에 읽을 수 있는 데이터가 1바이트 이상 있는지 여부를 나타냅니다. 이 표에서는POLLIN
해당 필드에 가 지정되어 있다고 가정합니다 .events
poll()
....
표 63-4: 파이프 또는 FIFO의 읽기 끝을 위한
select()
지침poll()
Condition or event | select() | poll() Data in pipe? | Write end open? | no | no | r | POLLHUP yes | yes | r | POLLIN yes | no | r | POLLIN | POLLHUP
표 63-5: 파이프 끝 또는 FIFO 쓰기 표시
select()
(이 표에서는 이벤트 필드에 지정되어 있다고 가정합니다.)poll()
POLLOUT
poll()
Condition or event | select() | poll() Space for PIPE_BUF bytes? | Read end open? | no | no | w | POLLERR yes | yes | w | POLLOUT yes | no | w | POLLOUT | POLLERR
두 테이블 모두의 첫 번째 행 조건을 이해하지 못합니다.
파이프에 데이터가 없고 쓰기 끝이 닫혀 있습니다. select()
이는 파일 설명자가 읽을 수 있는 파일 설명자라는 의미입니까? 왜? select()
파이프에 데이터가 있을 때까지 차단하면 안 되나요?
바이트 공간이 없고 PIPE_BUF
읽기 측이 닫혀 있습니다. select()
이는 쓰기 가능한 파일 설명자라는 것을 의미합니까?
답변1
파이프(읽기 쪽)를 열었다고 가정하면 데이터가 없습니다.하지만글쓰기 쪽도 열려있습니다. 이 경우에 다음을 수행 하면 read()
차단되며 select()
FD는 읽을 수 있는 것으로 보고되지 않습니다. 내 생각엔 우리가 그 점에 동의한 것 같아요, 그렇죠?
이제 당신이 이 막힌 부분에 있고 read()
작성자가 close()
파이프라인의 한쪽 끝에 있다고 상상해 보십시오. 무슨 일이야? read()
결과는 다음 과 같습니다 0
. 전화해도 거의 같은 일이 발생합니다.read()
뒤쪽에작가님 close
만 차단하지 않습니다. read
즉시 결과와 함께 반환됩니다 0
. 따라서 귀하가 인용한 소스의 추론에 따르면 귀하의 FD는 "읽을 수 있음"입니다. 또는 select
실제로 보고된 내용은 "중지할 수 없음"이라고 말하는 것이 더 좋습니다.
작은 예제를 작성해 보면 이 정의가 실제로 제안한 "직관적인" 정의보다 더 깨끗하고 우아한 코드가 된다는 것을 알게 될 것입니다.
답변2
쓰기 측이 이전에 열린 적이 없는 경우(예: Linux에서) 시스템 호출 select(2)(및 poll(2))는 FIFO의 읽기 측에서 차단됩니다.
반대로, 쓰기 측이 닫히면 PIPE의 읽기 측도 차단되지 않습니다.
차이점은 FIFO는 양쪽 끝이 닫힌 상태로 생성되는 반면 파이프는 양쪽 끝이 열린 상태로 생성된다는 것입니다. select(2) (및 poll(2))는 차단 동기화만 존재했던 Unix 초기에 발생한 일을 재현합니다(select(2) 및 BSD 소켓 API가 도입되기 전 - 일반적으로 비차단이 도입되기 전) Unix ).
쓰기 쪽도 열릴 때까지는 FIFO의 읽기 쪽을 성공적으로 열 수 없으므로 read(2)는 항상 쓰기 쪽이 열려 있는 FIFO를 찾습니다. 따라서 쓰기 측이 이전에 열린 적이 없는 경우 FIFO의 읽기 측에서 select(2)와 poll(2)이 모두 차단되는 것이 논리적입니다(읽기 측이 O_NONBLOCK으로 열린 경우에만 가능함).
예, 표 63-4의 FIFO에 대한 LPI는 쓰기 측이 한 번 이상 열려 있고 마지막 작성자에 의해 닫힌 경우에만 정확합니다.