Наши партнеры








Книги по Linux (с отзывами читателей)

Библиотека сайта rus-linux.net

На главную -> MyLDP -> Электронные книги по ОС Linux
Цилюрик О.И. Linux-инструменты для Windows-программистов
Назад Библиотеки API POSIX Вперед

Расширенные операции ввода-вывода

К этой части обычно относят рассмотрение синхронного-асинхронного ввода-вывода, и вызовы select(), pselect(), poll(), epoll(). Пожалуй, самую ясную и строгую классификацию моделей ввода-вывода в UNIX дал У. Р. Стивенс в [3] :

Прежде чем начать описание функций select и poll, мы должны вернуться назад и уяснить основные различия между пятью моделями ввода-вывода, доступными нам в Unix:

- блокируемый ввод-вывод;

- неблокируемый ввод-вывод;

- мультиплексирование ввода-вывода (функции select и poll);

- ввод-вывод, управляемый сигналом (сигнал SIGIO);

- асинхронный ввод-вывод (функции POSIX.1 aio_).

Блокируемый ввод — это самый часто используемый, и самый известный вариант, когда выполняется операция read(), или даже элементарные вызовы getchar() или gets(), выполняемые в каноническом режиме ввода с терминала (консоли). Эта модель ввода-вывода не нуждается в детальных комментариях.

Неблокирующий ввод-вывод

Неблокирующий ввод-вывод не ожидает наличия данных (или возможности вывода), результат выполнения операции, или невозможность её выполнения в данный момент определяется по анализу кода возврата. Пример (файл e5.cc архива fork.tgz) неблокирующего ввода был показан выше (в примере запуска дочернего процесса-фильтра). Схематично (убрано всё лишнее) это выглядит так:

int fo[ 2 ];                              // pipe – для чтения из дочернего процесса
if( pipe( fo ) ) perror( "pipe" ), exit( EXIT_FAILURE ); 
close( fo[ 1 ] ); 
int cur_flg = fcntl( fo[ 0 ], F_GETFL );  // чтение должно быть в режиме O_NONBLOCK
if( -1 == fcntl( fo[ 0 ], F_SETFL, cur_flg | O_NONBLOCK ) ) 
   perror( "fcntl" ), exit( EXIT_FAILURE ); 
...
while( 1 ) {
   int n = read( fdi, buf, buflen );
   if( n > 0 ) {
                                         // считаны данные ... обработка
   } 
   else if( -1 == n ) { 
      if( EAGAIN == errno ) {            // данные не готовы
         printf( "not ready!\n" );
         usleep( 300 ); 
         continue;
      } 
      else perror( "\nread pipe" ), exit( EXIT_FAILURE ); 
   }
}

Целая подборка примеров, относящихся к неблокирующему вводу-выводу, применительно к сетевым сокетам, заимствованных из [3] (потребовавших минимальных изменений), находится в архиве ufd.tgz каталог nonblock.


Предыдущий раздел: Оглавление Следующий раздел:
Сигналы в потоках   Мультиплексирование ввода-вывода