При использовании функции fcntl () для установки неблокирующего состоянии дескриптора файла нужно учитывать следующее. Поскольку неблокирующее поведение — это только одна из опций, которая может быть установлена в битовой маске флажков, вначале нужно вызвать команду F_GETFL, определить, какие опции уже установлены, затем установить бит O_N0NBL0CK с помощью поразрядной операции “ИЛИ” и только после этого вызвать команду F_SETFL для применения новых значений флажков к дескриптору. Именно таким образом можно получить процесс, например, получения веб страницы с информацией о конвекторах отопления внутрипольных или описанием другого продукта.
Ниже приведена небольшая подпрограмма, blocking (), которая иллюстрирует указанный порядок действий. Первым параметром процедуры является дескриптор файла, а вторым (необязательным) — логическое значение, которое может применяться для включения или выключения блокирующего состояния. При вызове без второго параметра подпрограмма возвращает истинное значение, если дескриптор файла является блокирующим; в ином случае — ложное.
use Fcntl; sub blocking { my ($handle,$b!ocking) = @_; die "Can’t fcntl(F_GETFL) " unless my $flacrs fcntl ($handle,F_GETFL, 6) ; my $current =($flags & O_NONBLOCK) == 0; if (defined $blocking) { $flags &= ~O_N0NBL0CK if $nonblосking ; $flags |= O_N0NBL0CK unless $blocking; die ."Can't fcntl(F_SETFL) " unless fcntl($handle,F_SETFL,$flags) ; } return $current; }
Обратите внимание, что сокеты по умолчанию начинают свою работу как блокирующие. Для перевода их в неблокирующее состояние необходимо вызвать подпрограмму blocking () с параметром 0.
I warn "making socket- nonblocking";
blocking ($sock, 0) ;
Дополнительная информация о функции fcntl () приведена в документе POD реrlfunc дистрибутива Perl.
Создание неблокирующих дескрипторов: объектно-ориентированный интерфейс
При использовании объектно-ориентированных модулей IO::Socket или IO::File установка неблокирующего режима сводится просто к вызову метода blocking () дескриптора.
$blocking_status = $handle->blocking ([$boolean])
При вызове без параметров метод blocking ( ) возвращает текущее состояние блокировки ввода-вывода для дескриптора. Истинное значение указывает, что дескриптор находится в обычном блокирующем режиме, а ложное — что активизирован неблокирующий ввод-вывод. Для изменения состояния блокировки дескриптора может быть задано логическое значение при вызове метода blocking ( ). После вызова метода с ложным значением сокет становится неблокирующим, а после первого вызова с истинным значением восстанавливается обычное блокирующее поведение.