Как зациклить select() для опроса данных до бесконечности

#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/types.h>

int main ()
{
char            name[20];
fd_set          input_set;
struct timeval  timeout;
int             ready_for_reading = 0;
int             read_bytes = 0;

/* Empty the FD Set */
FD_ZERO(&input_set );
/* Listen to the input descriptor */
FD_SET(0, &input_set);

/* Waiting for some seconds */
timeout.tv_sec = 10;    // 10 seconds
timeout.tv_usec = 0;    // 0 milliseconds

/* Invitation for the user to write something */
printf("Enter Username: (in 15 seconds)\n");
printf("Time start now!!!\n");

/* Listening for input stream for any activity */
ready_for_reading = select(1, &input_set, NULL, NULL, &timeout);
/* Here, first parameter is value of the socket descriptor + 1 (STDIN descriptor is 0, so  
 * 0 +1 = 1)  
 * in the set, second is our FD set for reading,
 * third is the FD set in which any write activity needs to updated, which is not required
 * in this case. Fourth is timeout
 */

if (ready_for_reading == -1) {
    /* Some error has occured in input */
    printf("Unable to read your input\n");
    return -1;
} else {
    if (ready_for_reading) {
        read_bytes = read(0, name, 19);
        printf("Read, %d bytes from input : %s \n", read_bytes, name);
    } else {
        printf(" 10 Seconds are over - no data input \n");
    }
}

return 0;

}

Как сделать то же самое, но не один раз, а в бесконечном цикле, который прерывается после появления строки 'quit' (например). Как ни пробовал - безуспешно. Таким образом, если в течение 10 секунд не было введено никаких данных, программа просто печатает «10 секунд истекли — ввод данных отсутствует» и снова начинает ждать. То же самое после ввода - просто начинается снова и ведет себя одинаково каждый раз в бесконечном цикле.
Я уже немного отчаялся, пожалуйста - помогите.
Спасибо.


person azrahel    schedule 19.05.2012    source источник
comment
Поместить все в цикл while(!strcmp(name, "quit")) или что-то в этом роде? :-)   -  person Eitan T    schedule 19.05.2012
comment
Здесь первый параметр — количество FD в наборе no. Это должен быть наибольший номер FD плюс один. Пожалуйста, перепроверьте справочную страницу.   -  person Mat    schedule 19.05.2012
comment
Пример внизу linux.die.net/man/2/select_tut: именно то, что вы хотите.   -  person Adam Liss    schedule 19.05.2012
comment
@EitanT попробуй сделать это с помощью while(1), и ты поймешь мой вопрос;)   -  person azrahel    schedule 19.05.2012
comment
@user471548 user471548 Вы также пытались включить в цикл FD_ZERO и FD_SET?   -  person Eitan T    schedule 19.05.2012
comment
@Mat, да, я знаю, не заметил, я скопировал код из другой темы. Фиксированный.   -  person azrahel    schedule 19.05.2012
comment
@ ЭйтанТ нет. и понятия не имею, как это сделать. Не могли бы вы предоставить фрагмент кода?   -  person azrahel    schedule 19.05.2012
comment
@ user471548, я изложил для вас общую идею в своем ответе. Посмотрите, работает ли это для вас...   -  person Eitan T    schedule 19.05.2012


Ответы (2)


Я не вижу здесь проблемы. По сути, просто поместите все, что хотите, в цикл и дайте ему работать. Вы пробовали это?

int main ()
{
   /* Declarations and stuff */
   /* ... */

   /* The loop */
   int break_condition = 0;
   while (!break_condition)
   {
       /* Selection */
       FD_ZERO(&input_set );   /* Empty the FD Set */
       FD_SET(0, &input_set);  /* Listen to the input descriptor */
       ready_for_reading = select(1, &input_set, NULL, NULL, &timeout);

       /* Selection handling */
       if (ready_for_reading)
       {
          /* Do something clever with the input */
       }
       else
       {
          /* Handle the error */
       }

       /* Test the breaking condition */
       break_condition = some_calculation();
   }
   return 0;
}

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

person Eitan T    schedule 19.05.2012
comment
Всем большое спасибо. Наконец-то решено! :))) Проблема заключалась в том, что я инициализировал аргументы выбора только один раз, а затем использовал их несколько раз, в то время как я должен инициализировать их каждый раз, когда использую выбор. Действительно большое спасибо. !!!! Привет - person azrahel; 19.05.2012

Функцию select() можно указать блокировать на неопределенный срок, установив для параметра timeout значение NULL. См. справочную страницу select(2):

время ожидания – это верхняя граница времени, прошедшего до возврата select(). Если оба поля структуры timeval равны нулю, функция select() возвращается немедленно. (Это полезно для опроса.) Если timeout равен NULL (без тайм-аута), select() может блокироваться на неопределенный срок.

Итак, что вы хотите:

...
ready_for_reading = select(1, &input_set, NULL, NULL, NULL);
...
person math    schedule 19.05.2012