Как мне выполнить неблокирующее fopen для именованного канала (mkfifo)? - PullRequest
17 голосов
/ 24 февраля 2009

Если у меня есть программа, которая создает и пытается открыть именованный канал с помощью mkfifo, как я могу открыть канал для чтения или записи без блокировки?

В частности, я пишу программу на C, которую можно запускать с графическим интерфейсом или без него (написанный на Java).

В программе на C я успешно создаю именованные каналы, используя mkfifo, однако, когда я делаю

FILE* in = fopen(PIPE_IN, "r"); /* Where PIPE_IN is the filename*/

fopen не возвращается, пока графический интерфейс не откроет этот канал для записи. Что я хочу сделать, так это подготовить этот канал для чтения один раз (если) GUI решит записать в него - я буду помещать дескриптор файла в вызов select (). Разумно ожидать, что java GUI на самом деле никогда не запустится, поэтому я не могу рассчитывать на то, что он откроет другой конец канала в какой-то конкретной точке или даже вообще.

У меня также будет открыт второй канал для записи, и я предполагаю, что у меня будет та же проблема. Кроме того, я не могу установить O_NONBLOCK для выходного канала, у которого нет читателя.

Есть предложения?

(Это работает в системе Linux)

1 Ответ

14 голосов
/ 24 февраля 2009

Вы можете open() свой канал O_RDONLY | O_NONBLOCK, и если вам нужен поток C, вы можете получить его с помощью fdopen(). Однако, может быть проблема с select() - AFAIK, открытый для чтения канал, у которого нет записывающего, всегда готов к чтению, и read() возвращает 0, поэтому select() будет работать бесконечно.

Хитрый способ преодолеть это - открыть трубу O_RDWR; то есть иметь как минимум одного писателя (вашу программу на C ++). Что решит вашу проблему в любом случае.

...