2016-02-10 3 views
0

У меня проблема с read() блокировкой моей программы при попытке прочитать из fifo. Я хочу, чтобы моя программа читала из нескольких файловых дескрипторов, и, хотя в ней есть информация, она будет записывать ее на стандартный вывод.select blocks fifo from reading

Я попытался использовать select, но, похоже, не работает.

main.c (есть п число второй программы)

for(i=0;i<n;i++) 
{ 
    fd[i] = open(myfifo[i], O_RDWR); 
    printf("%s\n",myfifo[i]); 
} 
while(1) 
{ 
     for(i=0;i<n;i++) 
     { 
      FD_ZERO(&set); 
      FD_SET(fd[i], &set); 
      n = select(fd[i]+1, &set, NULL, NULL, NULL); 
      if (n > 0) 
      { 
       r = read(fd[i], &demon1, sizeof(demon1)); 
       if(r !=-1) 
       { 
        /*READ DATA*/ 
       } 
      } 
     }  
} 

вторая программа (есть п число этой программы)

void signal_handler(int signum) 
{ 
if (signum == SIGUSR1) 
{ 
    /*STAFF*/ 
    mkfifo(myfifo, 0666); 
    fd = open(myfifo, O_RDWR); 
    write(fd, &demon1 , sizeof(demon1)); 
    close(fd); 
} 
} 

каждая программа ФИФО по имени myfifo1, myfifo2 .. и так далее. Пожалуйста, помогите.

EDIT: Теперь у меня есть это:

int max_fd; 
while(1) 
{ 
FD_ZERO(&set); 
for(i=0;i<n;i++) 
{ 
    FD_SET(fd[i], &set); 
    if (fd[i]>max_fd) max_fd = fd[i]; 
} 
n = select(max_fd+1, &set, NULL, NULL, NULL); 
if (n != 0) 
{ 
    int d; 
    for (d = 0; d<FD_SETSIZE; d++) 
    { 
     if (FD_ISSET(d,&set)) 
     { 
      r = read(d, &demon1, sizeof(demon1)); 
      if(r !=-1) 
      { 
       /*CODE*/ 
      } 
     } 
    } 
} 
} 

Читает правильно только на первой попытки, потом он читает только первый FileDescriptor

по-видимому, есть разностное между

//n = select(max_fd+1, &set, NULL, NULL, NULL); 
//if (n != -1) 

и

if (select(max_fd+1, &set, NULL, NULL, NULL) != -1) 

EDIT: Кажется, работает только на ubuntu virutal machine .. linux mint laptop нет.

+0

Вы используете 'select' неправильно. Его не следует вызывать для каждого fd. Основной момент 'select' заключается в том, что он может контролировать несколько fds за один вызов. Вы должны заполнить 'set' всеми fds и сделать один вызов' select' для всех из них. – kaylum

+0

Вы не должны нормально открывать fifos таким образом, вы должны открывать для чтения или для записи, а не для чтения и записи на одном и том же дескрипторе. –

+0

с блокирующим режимом? Я не думаю, что это причина? – Thomas

ответ

1

Нет вы должны построить набор для чтения, а затем сделать вызов выберите:

// Create the set of descriptor to select on 
FD_ZERO(&set); 
max_fd = 0; 
for (i=0; i<n; i++) { 
    FD_SET(fd[i], &set);    // add the descriptor to the set 
    if (fd[i]>max_fd) max_fd = fd[i]; // register the highest descriptor 
} 

// Then select on the set of descriptors 
if (select(max_fd+1, &set, NULL, NULL, NULL)!=-1) { 
    // extract which descriptors are available for reading 
    for (int d=0; d<FD_SETSIZE; d++) { 
     if (FD_ISSET(d,&set)) { 
      // something to read in descriptor d 
     } 
    } 
} 
+0

Я думаю, что это должно быть, если (выберите (max_fd + 1, & set, NULL, NULL, NULL)! = - 1), так или иначе это не сработает. Теперь он читается только из последнего дескриптора – Thomas

+0

На самом деле он читается только с первого, который отправит сообщение. Msg – Thomas

+0

Что-то не так где-то в другом месте. Наблюдайте за значением набора до и после выбора. Если что-то некогерентно, найдите проблему соответствующим образом. Если значения являются когерентными, что-то может поступить неправильно в отправляющей части ... –