2016-01-11 2 views
1

У меня есть два процесса, первое чтение из stdin и запись в файл FIFO, второй - сообщение из файла FIFO.Как остановить чтение fgets из файла FIFO

Я использую эту структуру программы:

while(run) 
{ 
    fgets(string, sizeof(string), fp); 
} 

и когда дозорный (бег) изменение в 0, чтобы остановить процесс, это на самом деле не остановить, потому что он застрял в fgets() функции. Как я могу это решить?

Я хочу, чтобы программа ожидала сообщения, когда дозорный сигнал изменился на 0, а затем немедленно остановите программу.

+1

Обычный способ сделать это - использовать 'select' для ожидания ввода перед вызовом' fgets'. Чтобы разразиться рано, очистите 'run', а затем отправьте сигнал процессу. Сигнал будет прерывать 'select', он вернется к началу цикла, посмотрите, что' run' очистился и, таким образом, выйдет. – kaylum

+0

Можете ли вы рассказать, как это будет выглядеть в этом конкретном случае? –

+0

Другой вариант - использовать обработчик сигнала для очистки 'run'. Если обработчик установлен без флага 'SA_RESTART', его доставка прервет любые блокирующие чтения/записи syscalls в том же потоке. Лично я использую низкоуровневые (unistd.h) операции ввода-вывода, неблокирования и select(). –

ответ

0

Я думаю, что здесь ваш ФИФО открыт в блокирующем режиме, поэтому в fgets() для чтения вызова, если данные не доступны, что вызов будет заблокирован до ФИФО имеет некоторые новые данные.

SO, чтобы избежать этого открытого FIFO в неблокирующем режиме, используя O_NONBLOCK в открытом вызове.

Подробнее здесь. http://www.tldp.org/LDP/lpg/node19.html

Таким образом, если данные отсутствуют, fgets с возвратом с ошибкой вместо того, чтобы закрепить этот вызов. В следующем цикле проверки run будет 0, поэтому он выйдет из этого цикла.

+0

, чтобы открыть fifo, я использую функцию fopen(). Могу ли я установить что-то подобное в fopen ?? –

+0

См. Это http://stackoverflow.com/questions/580013/how-do-i-perform-a-non-blocking-fopen-on-a-named-pipe-mkfifo Используя open() open fifo, а затем используя fdopen() конвертировать дескриптор файла в указатель файла, а затем выполнить всю операцию с файлом –

+0

У меня возникла эта проблема, когда я использую fdopen: Ошибка сегментации (сбрасывание ядра) –

Смежные вопросы