2012-09-17 3 views
0

신호에 응답하지 않는 경우 서로 협력 4 개 어린이에 주요 공정 포크 :에서 한 번에 1 바이트를 읽어잠자는 과정은 내가 프로그램을 가지고

process0는 FIFO 파일 (O_WRONLY)을 열어 가고 있습니다, 읽기 기능을 사용하는 STDIN 쓰기 및 닫기 FIFO 파일을 사용하여 FIFO에 쓰기

process1 공유 메모리가 비어 있기를 기다리고 있습니다. (탭 (0) == 0) 인 경우 공유 메모리 테이블의 첫 번째 바이트를 사용합니다. 그것의 비어 있음을 확인) FIFO 파일 (O_RDONLY)을 열어서이 1 바이트를 16 진수로 변환하고 공유 메모리에 저장합니다. 그러므로 FIFO를 폐쇄하고 읽은 후 탭 [0] == 1.

process3이다 파이프에 데이터를 기록하는 경우, 공유 메모리로부터 판독되는 1

process2에 탭 [0] 공유 메모리 테이블을 설정 파이프에서 읽기 및 STDIN에 쓰기

이 모든 것이 완벽하게 작동합니다. 신호를 추가하려고 할 때 문제가 시작되었습니다. 세마포어를 사용하여 p0과 p1을 동기화하고 p1과 p2를 동기화하고 p2와 p3을 동기화하는 메시지 큐를 동기화합니다. 예를 들어 process1이 휴면 모드에있는 경우를 제외하고는 잘 작동합니다. 그것은 FIFO에서 읽기를 원할 때이 모드로 들어가고 데이터가 전송 될 때까지 기다려야합니다. 나는 그것에 대해 읽었습니다. 여기

processes hierarchy

내가 원인 일 수 있습니다 생각하는 것으로 나타났습니다 내용은 다음과 같습니다

"사용자 모드에서 (1),이 상태 2를로 이동하는 동안 프로세스는 시스템 호출을하면 이 시점에서 하드 디스크의 파일을 읽는 것이 시스템 호출이라고 가정하자. 읽기가 즉시 수행되지 않기 때문에 프로세스는 시스템이 읽었을 때까지 기다리면서 sleep 상태가된다. 데이터가 준비되면 프로세스가 각성됩니다. 즉, 즉시 실행된다는 의미가 아니라 주 메모리 (3)로 다시 실행할 준비가 된 것입니다. "

나는 그것을 이해할 수 있다고 생각하지만 어떻게 이것을 피할 수 있습니까? 내 프로그램이 항상 신호에 반응하기를 바랍니다. "kill"을 통해 신호를 보낼 때 프로세스 상태를 sleep에서 running으로 변경하는 방법이 있습니까? 시스템이 디스크를 읽었고 데이터가 준비되었다는 이벤트를 기다리지 못하게 프로세스에 알릴 수 있습니까?

Program's code

답변

1

내가 제대로 질문을 이해한다면, 과정 1 라인 (442) (소스)에서 끊었지고 있으며이 때문에 신호에 응답하지 : 누군가가보고 싶은 경우

여기 내 코드입니다 read

확실한 대답은 차단을하지 않는 것입니다. read(). 설명자를 검사하여 읽을 수있는 항목이 있는지 확인하십시오. fcntl/ioctl을 읽고 비 차단 읽기를 수행하는 방법.

1

신호가 발생할 경우 (대부분의) 시스템 호출이 기본값으로 재시작 될 가능성이 있습니다. 간단히 말하면, 시스템 호출에서 멈춰있는 코드는 신호가 전달 될 때 사용자 영역을 깨우지 만 신호 처리기가 실행 된 후 시스템 호출을 다시 시작한다는 의미입니다.

sigaction()을 사용하여 signal() 함수 대신 신호 처리기를 설정하는 경우.시그널이 잡히면 시스템 콜은 재시작되지 않고 errno를 실패로 설정하고 EINTR로 설정한다. 즉, 시스템 호출이 전달되는 신호로 인해 "실패"할 수 있다는 사실을 처리해야한다는 것을 의미합니다.

(기본적으로 signal()은 linux가 다시 시작될 때 시스템 호출을 발생 시키므로 signal.h 헤더를 포함하기 전에 일부 기능 매크로에 의해 제어 될 수 있습니다 .SIGaction()이 시스템 호출을 재시작하게하는지 여부는 플래그 SA_RESTART 신호 처리기를 설정할 때)