2009-02-24 7 views
17

mkfifo를 사용하여 명명 된 파이프를 만들고 열려고하는 프로그램이있는 경우 차단하지 않고 읽기 또는 쓰기 용 파이프를 열려면 어떻게해야합니까?명명 된 파이프 (mkfifo)에서 비 차단 fopen은 어떻게 수행합니까?

특히 나는 gui (Java로 작성된)와 함께 또는없이 실행될 수있는 C 프로그램을 작성하고 있습니다. GUI를 열릴 때까지 C 프로그램에서

, 나는 성공적으로 내가
FILE* in = fopen(PIPE_IN, "r"); /* Where PIPE_IN is the filename*/ 

fopen을

는 반환하지 않습니다 할 그러나 때,에서는 mkfifo를 사용하여 명명 된 파이프를 만들 것을 쓰기 위해 파이프. 내가하고 싶은 것은 그 파이프를 한번 읽을 준비가되어 있다면 (만약에) GUI가 그것에 쓰기를 결정한다면 - 나는 파일 기술자를 select() 호출에 넣을 것이다. 자바 GUI가 결코 실제로 시작되지 않을 것이라는 점을 예상하는 것이 합리적입니다. 그래서 특정 지점이나 심지어는 파이프의 다른 쪽 끝을 열 수는 없습니다.

필자는 두 번째 파이프를 작성 용으로 열어두고 동일한 문제가 있다고 가정합니다. 또한 판독기가없는 출력 파이프에 O_NONBLOCK을 설정할 수 없습니다.

어떤 제안?

(이것은 리눅스 시스템에서 실행되는)

+0

입력 파이프에서 select()를 실행하기 전에 출력 파이프를 열어야합니까? –

+0

@tinkertim - 기술적으로는 그렇지 않다고 가정합니다. 설치 기능에서이 두 가지를 모두 설정했지만 출력 파이프를 먼저 설정 한 다음 select를 호출 할 수 있습니다. 이유는 무엇입니까? – Zxaos

답변

12

당신은 당신의 파이프 O_RDONLY | O_NONBLOCKopen() 수 있고, 당신이 C 스트림을 원한다면, 당신은 fdopen() 그것을 얻을 수 있습니다. 그러나 select() - AFAIK에 문제가있을 수 있습니다. 판독기가없는 읽기 용으로 열려있는 파이프 fd는 항상 읽을 준비가되어 있고 read()은 0을 반환하므로 select()이 무기한 실행됩니다.

이 문제를 극복하기위한 좋은 방법은 파이프를 여는 것입니다. O_RDWR; 즉 적어도 한 명의 작가 (C++ 프로그램)가 있어야합니다. 어쨌든 당신의 문제를 해결할 것입니다.

+1

나는 그걸 독자에게 줄 것이다. 그러나 출력 파이프에 O_NONBLOCK을 설정할 수 없다. ... – Zxaos

+1

POSIX 표준은 (select() 중) : "설명자는 호출 할 때 읽기 준비가되어 있어야한다. 함수가 데이터를 성공적으로 전송하는지 여부와 상관없이 O_NONBLOCK을 사용하는 입력 함수는 차단하지 않습니다. " (POSIX.1 : 2008). –

+1

O_RDWR 파이프를 열면 프로그램을 읽거나 쓸 때 교착 상태가 발생합니다. 파이프가 열려있는 다른 프로세스가 실제로 있지 않는 한. –