read()
및 write()
통화 매뉴얼 페이지를 읽음으로써 이러한 통화는 차단 여부와 상관없이 신호에 의해 중단 된 것으로 보입니다.
특히, 가정
- 프로세스는 일부 신호에 대한 핸들러를 설정합니다.
- 설정
O_NONBLOCK
되지 않은 상태 로 장치가 열린 경우 (예 : 터미널) (예 : 차단 모드에서 작동) - 그러면 프로세스
read()
는 장치에서 시스템 호출을 읽어 커널 공간에서 커널 제어 경로를 실행합니다. - 선행 작업이
read()
커널 공간에서 실행 되는 동안 핸들러가 이전에 설치된 신호가 해당 프로세스로 전달되고 해당 신호 핸들러가 호출됩니다.
SUSv3 'XSH (System Interfaces Volume)' 매뉴얼 페이지와 해당 섹션을 읽으면 다음과 같은 사실을 알 수 있습니다.
나는. read()
데이터를 읽기 전에 신호에 의해 a 가 중단 되면 (즉, 사용 가능한 데이터가 없기 때문에 차단해야 함) errno
[EINTR] 로 설정하여 -1을 반환합니다 .
ii. a read()
가 일부 데이터를 성공적으로 읽은 후 신호에 의해 중단 된 경우 (즉, 즉시 요청 서비스를 시작할 수있는 경우) 읽은 바이트 수를 반환합니다.
질문 A) :
어느 경우이든 (블록 / 블록 없음) 신호의 전달 및 처리가 완전히 투명하지 않다고 가정하는 것이 옳은가 read()
?
사례 i. 블로킹 read()
은 일반적으로 프로세스가 TASK_INTERRUPTIBLE
상태에 놓이게되므로 신호가 전달 될 때 커널이 프로세스를 TASK_RUNNING
상태에 놓기 때문에 이해할 수있는 것 같습니다 .
그러나 read()
차단 할 필요가 없으며 (case ii.) 커널 공간에서 요청을 처리 할 때 신호 도착 및 처리가 HW의 도착 및 적절한 처리와 같이 투명 할 것이라고 생각했을 것입니다 방해가 될 것입니다. 특히 신호를 전달할 때 프로세스가 일시적으로 사용자 모드 로 설정 되어 신호 처리기를 실행하여 결국 인터럽트 된 read()
(커널 공간에서) 처리를 끝내기 위해 반환되는 신호 처리기를 read()
실행합니다. 그 후 프로세스는 read()
(사용자 공간에서) 호출 직후의 지점으로 되돌아 가고 결과적으로 사용 가능한 모든 바이트가 읽 힙니다.
그러나 ii. 는 read()
데이터를 즉시 사용할 수 있기 때문에가 중단 되었음을 의미하는 것으로 보이지만 일부 데이터 만 반환합니다 (모두 대신).
이것은 나의 두 번째 (마지막) 질문으로 연결됩니다.
질문 B) :
A)의 가정이 맞다 read()
면 요청을 즉시 충족시키기 위해 사용할 수있는 데이터가 있기 때문에 차단할 필요가 없는데 왜 중단이 발생합니까? 다시 말해, read()
신호 처리기를 실행 한 후 왜 재개되지 않는가? 결과적으로 사용 가능한 모든 데이터 (결국 사용 가능)가 반환되는 이유는 무엇입니까?