Операционные системы. Учебное пособие. Марапулец Ю.В. - 185 стр.

UptoLike

Составители: 

PIPE_WAIT. Проще всего эту команду использовать с каналами, которые обеспечивают
возможность ожидания.
Значения TRUE и FALSE, возвращаемые функцией ConnectNamedPipe(), являются
несколько неестественными. В частности, значение TRUE возвращается только в том
случае, если канал начинает свое существование в состоянии ожидания, а клиент под-
ключается после выполнения команды соединения, но до ее завершения. Если канал уже
подключен к клиенту и команда работает асинхронно (завершается без ожидания) или
если она вызывается для канала, который не допускает ожидания, функция ConnectNa-
medPipe() всегда возвращает значение FALSE.
Функция ожидания клиента WaitNamedPipe() реально не устанавливает никакого
соединения. Она возвращает значение TRUE, если канал доступен или становится дос-
тупным впоследствии; однако дескриптор существующего канала эта функция не воз-
вращает.
Клиент обычно циклически выполняет последовательность операций ожидания и
создания до тех пор, пока не будет получен действительный дескриптор канала. Функ-
ция WaitNamedPipe() считает канал доступным только в том случае, если сервер вызы-
вает функцию ConnectNamedPipe() в ожидании связи. Две эти функции работают вместе,
синхронизируя действия клиента и сервера. Однако если сервер создает новый канал,
который никогда не подключался ни к одному из клиентов, функция WaitNamedPipe()
возвращает значение TRUE, даже если это противоречит результату функции Connect-
NamedPipe(). Гарантировать соединение с помощью функции WaitNamedPipe() можно
только в том случае, если серверу известно о доступности канала. Если клиент разрыва-
ет соединение, сервер может ошибочно отреагировать на это событие. Кроме того, при
немедленном подключении нового клиента сервер не может знать о наличии нового
партнера. Распознавание только новых каналов и каналов, сформированных с помощью
функций ConnectNamedPipe() и WaitNamedPipe(), предотвращает отключение клиентов
во время процесса обмена информацией.
Следует отметить, что функция WaitForSingleObject() не работает с каналами, по-
скольку они не имеют сигнального состояния.
Для осуществлении связи по дуплексным каналам используется две функции:
TransactNamedPipe() и CallNamedPipe(). Эти функции комбинируют операции записи и
чтения в единой транзакции. Транзакции особенно полезны в сетях, поскольку они сво-
дят к минимуму количество сеансов передачи информации.
Поддержка взаимных транзакций возможна при условии, что канал соответствует
следующим условиям [12]:
является именованным;
использует флаг PIPE_ACCESS_DUPLEX;
относится к типу канала сообщений;
настроен на режим чтения сообщений.
Сервер устанавливает все эти атрибуты с помощью функции CreateNamedPipe().
При необходимости клиент может подкорректировать некоторые атрибуты с помощью
функции SetNamedPipeHandleState(). Режим блокировки не влияет на выполнение ко-
манд транзакций.
Отправление запроса
Функция TransactNamedPipe() отправляет запрос по каналу и ожидает ответа. Ис-
пользоваться она может как клиентами, так и серверами, хотя для первых она более по-
лезна.
BOOL TransactNamedPipe(
HANDLE hNamedPipe, // дескриптор именованного канала
LPVOID lpvWriteBuf, // буфер для хранения передаваемой
187
PIPE_WAIT. Проще всего эту команду использовать с каналами, которые обеспечивают
возможность ожидания.
      Значения TRUE и FALSE, возвращаемые функцией ConnectNamedPipe(), являются
несколько неестественными. В частности, значение TRUE возвращается только в том
случае, если канал начинает свое существование в состоянии ожидания, а клиент под-
ключается после выполнения команды соединения, но до ее завершения. Если канал уже
подключен к клиенту и команда работает асинхронно (завершается без ожидания) или
если она вызывается для канала, который не допускает ожидания, функция ConnectNa-
medPipe() всегда возвращает значение FALSE.
      Функция ожидания клиента WaitNamedPipe() реально не устанавливает никакого
соединения. Она возвращает значение TRUE, если канал доступен или становится дос-
тупным впоследствии; однако дескриптор существующего канала эта функция не воз-
вращает.
      Клиент обычно циклически выполняет последовательность операций ожидания и
создания до тех пор, пока не будет получен действительный дескриптор канала. Функ-
ция WaitNamedPipe() считает канал доступным только в том случае, если сервер вызы-
вает функцию ConnectNamedPipe() в ожидании связи. Две эти функции работают вместе,
синхронизируя действия клиента и сервера. Однако если сервер создает новый канал,
который никогда не подключался ни к одному из клиентов, функция WaitNamedPipe()
возвращает значение TRUE, даже если это противоречит результату функции Connect-
NamedPipe(). Гарантировать соединение с помощью функции WaitNamedPipe() можно
только в том случае, если серверу известно о доступности канала. Если клиент разрыва-
ет соединение, сервер может ошибочно отреагировать на это событие. Кроме того, при
немедленном подключении нового клиента сервер не может знать о наличии нового
партнера. Распознавание только новых каналов и каналов, сформированных с помощью
функций ConnectNamedPipe() и WaitNamedPipe(), предотвращает отключение клиентов
во время процесса обмена информацией.
      Следует отметить, что функция WaitForSingleObject() не работает с каналами, по-
скольку они не имеют сигнального состояния.
      Для осуществлении связи по дуплексным каналам используется две функции:
TransactNamedPipe() и CallNamedPipe(). Эти функции комбинируют операции записи и
чтения в единой транзакции. Транзакции особенно полезны в сетях, поскольку они сво-
дят к минимуму количество сеансов передачи информации.
      Поддержка взаимных транзакций возможна при условии, что канал соответствует
следующим условиям [12]:
• является именованным;
• использует флаг PIPE_ACCESS_DUPLEX;
• относится к типу канала сообщений;
• настроен на режим чтения сообщений.
      Сервер устанавливает все эти атрибуты с помощью функции CreateNamedPipe().
При необходимости клиент может подкорректировать некоторые атрибуты с помощью
функции SetNamedPipeHandleState(). Режим блокировки не влияет на выполнение ко-
манд транзакций.
Отправление запроса
      Функция TransactNamedPipe() отправляет запрос по каналу и ожидает ответа. Ис-
пользоваться она может как клиентами, так и серверами, хотя для первых она более по-
лезна.

BOOL TransactNamedPipe(
     HANDLE hNamedPipe,                // дескриптор именованного канала
     LPVOID lpvWriteBuf,               // буфер для хранения передаваемой

                                        187