Читаем Основы программирования в Linux полностью

Несмотря на то, что Linux модифицирует структуру, на которую указывает timeout, фиксируя оставшееся неиспользованное время, большинство версий UNIX этого не делают. Большая часть существующего программного кода, применяющего функцию select, инициализирует структуру типа timeval и затем продолжает использовать ее без обновления содержимого. В системе Linux этот код может выполняться некорректно, поскольку ОС Linux изменяет структуру timeval при каждом истечении отведенного времени ожидания. Если вы пишете или переносите программный код, использующий функцию select, следует учитывать эту разницу и всегда повторно инициализировать время ожидания. Имейте в виду, что оба подхода корректны, они просто разные!

Выполните упражнение 15.8.

Упражнение 15.8. Функция select

Далее для демонстрации применения функции select приведена программа select.c. Более сложный пример вы увидите чуть позже. Программа читает данные с клавиатуры (стандартный ввод — дескриптор 0) со временем ожидания 2,5 секунды. Данные читаются только тогда, когда ввод готов. Естественно расширить программу, включив в зависимости от характера приложения другие дескрипторы, такие как последовательные каналы (serial lines) и сокеты.

1. Начните как обычно с директив include и объявлений, а затем инициализируйте inputs для обработки ввода с клавиатуры:

#include

#include

#include

#include

#include

#include

#include

int main {

 char buffer[128];

 int result, nread;

 fd_set inputs, testfds;

 struct timeval timeout;

 FD_ZERO(&inputs);

 FD_SET(0, &inputs);

2. Подождите ввод из файла stdin в течение максимум 2,5 секунд:

 while(1) {

  testfds = inputs;

  timeout.tv_sec = 2;

  timeout.tv_usec = 500000;

  result = select(FD_SETSIZE, &testfds, (fd_set *)NULL,

   (fd_set*)NULL, &timeout);

3. Спустя это время проверьте result. Если ввода не было, программа выполнит цикл еще раз. Если в нем возникла ошибка, программа завершается:

  switch(result) {

  case 0:

   printf("timeout\n");

   break;

  case -1:

   perror("select");

   exit(1);

4. Если во время ожидания у вас наблюдаются некоторые действия, связанные с файловым дескриптором, читайте ввод из stdin и выводите его при каждом получении символа EOL (конец строки), до нажатой комбинации клавиш +:

  default:

   if (FD_ISSET(0, &testfds)) {

    ioctl(0, FIONREAD, &nread);

    if (nread == 0) {

     printf("keyboard done\n");

     exit(0);

    }

    nread = read(0, buffer, nread);

    buffer[nread] = 0;

    printf("read %d from keyboard: %s", nread, buffer);

   }

   break;

  }

 }

}

Во время выполнения эта программа каждые две с половиной секунды выводит строку timeout. Если вы набираете данные на клавиатуре, она читает файл стандартного ввода и отображает то, что было набрано. В большинстве командных оболочек ввод направляется в программу при нажатии пользователем клавиши (или ) или клавиш управляющей последовательности, поэтому программа будет отображать ввод каждый раз, когда вы нажимаете клавишу . Учтите, что сама клавиша тоже читается и обрабатывается как любой другой символ (попробуйте выполнить ввод без нажатия клавиши, введя ряд символов, за которыми следует комбинация +).

$ ./select

timeout

hello

read 6 from keyboard: hello

fred

read 5 from keyboard: fred

timeout

^D

keyboard done

$

Как это работает

Программа применяет вызов select для проверки состояния стандартного ввода. За счет корректировки значения времени ожидания программа каждые 2,5 секунды выводит сообщение об истечении времени ожидания. О нем свидетельствует возвращение 0 функцией select. При достижении конца файла дескриптор стандартного ввода помечается флагом как готовый к вводу, но при этом нет символов, предназначенных для считывания.

<p>Множественные клиенты</p>
Перейти на страницу:

Похожие книги

Основы программирования в Linux
Основы программирования в Linux

В четвертом издании популярного руководства даны основы программирования в операционной системе Linux. Рассмотрены: использование библиотек C/C++ и стан­дартных средств разработки, организация системных вызовов, файловый ввод/вывод, взаимодействие процессов, программирование средствами командной оболочки, создание графических пользовательских интерфейсов с помощью инструментальных средств GTK+ или Qt, применение сокетов и др. Описана компиляция программ, их компоновка c библиотеками и работа с терминальным вводом/выводом. Даны приемы написания приложений в средах GNOME® и KDE®, хранения данных с использованием СУБД MySQL® и отладки программ. Книга хорошо структурирована, что делает обучение легким и быстрым. Для начинающих Linux-программистов

Нейл Мэтью , Ричард Стоунс , Татьяна Коротяева

ОС и Сети / Программирование / Книги по IT
1001 совет по обустройству компьютера
1001 совет по обустройству компьютера

В книге собраны и обобщены советы по решению различных проблем, которые рано или поздно возникают при эксплуатации как экономичных нетбуков, так и современных настольных моделей. Все приведенные рецепты опробованы на практике и разбиты по темам: аппаратные средства персональных компьютеров, компьютерные сети и подключение к Интернету, установка, настройка и ремонт ОС Windows, работа в Интернете, защита от вирусов. Рассмотрены не только готовые решения внезапно возникающих проблем, но и ответы на многие вопросы, которые возникают еще до покупки компьютера. Приведен необходимый минимум технических сведений, позволяющий принять осознанное решение.Компакт-диск прилагается только к печатному изданию книги.

Юрий Всеволодович Ревич

Программирование, программы, базы данных / Интернет / Компьютерное «железо» / ОС и Сети / Программное обеспечение / Книги по IT