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()신호 처리기를 실행 한 후 왜 재개되지 않는가? 결과적으로 사용 가능한 모든 데이터 (결국 사용 가능)가 반환되는 이유는 무엇입니까?