2016-01-12 5 views
0

У меня действительно очень неприятная проблема при попытке прочитать из нескольких филонов. У меня есть 1 процесс, ожидающий структуры из fifo и нескольких процессов, которые отправляют ему эти структуры по сигналу. После первого чтения я не могу читать ничего больше .. из любого сигнала. Похоже, программа застывает.Невозможно прочитать из нескольких фиксов

Процесс отправки имеет это в основном с

myfifo = '/tmp/myfifo{0}' //{0} is a number that every process has individual. 
mkfifo(myfifo, 0666); 
fd = open(myfifo, O_WRONLY); 
write(fd, &demon1 , sizeof(demon1)); 
close(fd); 
while (1) 
{ 
} 

и это в signal_handler

void signal_handler(int signum) 
{ 
    if (signum == SIGUSR1) 
    { 
     //some declarations here 
     mkfifo(myfifo, 0666); 
     fd = open(myfifo, O_WRONLY | O_NONBLOCK); 
     write(fd, &demon1 , sizeof(demon1)); 
    } 
} 

Хотя процесс чтения имеет

myfifo[i] = /tmp/myfifo{0} // {0} is i which is the number of process that sends. 

while(1) 
{ 
    for(i=0;i<n;i++) 
    { 
     fd = open(myfifo[i], O_RDONLY | O_NONBLOCK); 
     r = read(fd, &demon1, sizeof(demon1)); 
     if(r > 1) 
     { 
      //printf struct elements 
     } 

    } 
    } 
+0

Пришлите минимальный рабочий пример. Вы, например, закрываете каждый fd снова после открытия в процессе _reading? В противном случае у вас скоро закончится файловый дескриптор – Ctx

+0

это по большей части - это все, что нужно для печати и настройки каталогов. – Thomas

+0

Я предлагаю прочитать вывод 'man 7 fifo', в частности, часть об открытии FIFO в режиме без блокировки. Я думаю, что ваш «только открытый», неблокирующий 'open' будет с ошибкой 'ENXIO', когда другой конец FIFO не будет открыт. –

ответ

1

Вы не закрыть filedescriptors после открытия и чтения:

while(1) 
{ 
    for(i=0;i<n;i++) 
    { 
     fd = open(myfifo[i], O_RDONLY | O_NONBLOCK); 
     r = read(fd, &demon1, sizeof(demon1)); 
     if(r > 1) 
     { 
      //printf struct elements 
     } 

Здесь отсутствует close(fd).

} 
} 

Поскольку открытая неблокирующая, максимальное количество FDS в процессе достигается очень скоро и последующее открывает потерпит неудачу.

+0

Это все еще не помогает, если я не отправил сообщение в myfifo [0], другие fifos не будут прочитаны – Thomas

+0

@Thomas Извините, я не понимаю этот комментарий, не могли бы вы рассказать немного больше о том, что происходит? – Ctx

+0

myfifo [0] имеет путь к первому fifo, если я не прочитаю его, я не буду проверять следующий. Например, если я отправил сначала myfifo [2] (третий путь), он будет ждать, пока не будет прочитано myfifo [0] и myfifo [1]. – Thomas

1

Вы открываете трубу внутри петли. Таким образом, вы быстро исчерпаете дескрипторы файлов (которые вы увидите, если вы проверили результат open() на наличие ошибок).

Я предлагаю открыть все FIFO за пределами цикла, сохранить дескрипторы файла в массиве, а затем просто прочитать каждый из них, но ... чтение будет блокироваться. См. select(2), чтобы узнать, какие данные FIFO имеют данные.

Другим решением будет один FIFO, и процесс записи должен отправить его идентификатор в сообщении. Таким образом, основной процесс просто должен прослушивать один FIFO. Если он хочет знать, кто отправил сообщение, он может посмотреть идентификатор в сообщении. Проблема здесь: вам нужна какая-то блокировка, или несколько процессов будут записываться в FIFO одновременно, а их данные может перепутаться (это зависит от буферов FIFO).

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