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

UptoLike

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

Другой метод реализации асинхронного ввода/вывода заключается в использова-
нии команд ReadFileEx() и WriteFileEx(). Вместо того чтобы сигнализировать о своем
завершении с помощью события, эти команды запускают специальную функцию, кото-
рая должна вызываться в конце каждой операции.
Применение асинхронного ввода/вывода представляет собой стратегический при-
ем, позволяющий осуществлять работу с несколькими клиентами, подключенными к
различным экземплярам одного канала. Операции синхронного ввода/вывода проще
программировать, однако медленные команды записи и чтения часто задерживают вы-
полнение других операций. Сервер может создавать отдельный поток для каждого кли-
ента, однако такой подход подразумевает гораздо большую степень избыточности, чем
того требует реальная ситуация.
При асинхронном вводе/выводе один и тот же поток может одновременно записы-
вать и читать данные в различных экземплярах канала, поскольку каждая из команд не-
медленно возвращает управление программе и освобождает поток, а операция вво-
да/вывода выполняется системой в фоновом режиме. С помощью команды
WaitForMultipleObjects() поток можно блокировать вплоть до завершения всех отложен-
ных операций. Эффективность асинхронного ввода/вывода особенно ярко проявляется
при медленных сетевых соединениях. Кроме того, при наличии меньшего числа синхро-
низируемых потоков гораздо проще обеспечить защиту программных ресурсов.
В любой момент клиент может вызвать функцию CreateFile() для открытия сво-
его конца именованного канала. Однако при этом могут возникнуть две проблемы [12].
Серверу иногда необходимо знать, подключился ли клиент к каналу. От операции
записи в неподключенный канал пользы немного, и функция CreateFile() не сообща-
ет серверу о наличии соединения.
Если все экземпляры канала заняты, функция CreateFile() постоянно возвращает
значение INVALID_HANDLE_VALUE, не устанавливая соединения. Клиент может
подождать, пока не освободится один из экземпляров канала, где будет завершена
операция, инициированная другим клиентом.
Короче говоря, и сервер, и клиент должны иметь возможность блокироваться,
ожидая условий, при которых выполнение подключения станет возможным. Для этого
сервер должен вызвать функцию ConnectNamedPipe(), а клиентфункцию WaitNamed-
Pipe().
BOOL ConnectNamedPipe(
HANDLE hNamedPipe, // дескриптор доступного именованного канала
LPOVERLAPPED lpOverlapped ); // поддержка асинхронного ввода/вывода
BOOL WaitNamedPipe(
LPTSTR lpszPipeName, // указывает на строку, которая задает
// имя канала
DWORD dwTimeout ); // максимальное время ожидания, миллисекунды
Эти координирующие функции работают только с именованными каналами, по-
скольку клиент не может создавать собственных дескрипторов анонимных каналов, он
должен получить дескриптор непосредственно от сервера, а в этом случае подключение
уже выполнено.
Подобно функциям ReadFile() и WriteFile(), функция ConnectNamedPipe() обеспе-
чивает асинхронную реакцию. Параметр lpOverlapped содержит дескриптор события,
которое будет служить сигналом об установке связи с клиентом.
Функционирование команды ConnectNamedPipe() зависит от того, был ли канал
создан с указанием флага FILE_FLAG_OVERLAPPED и находится ли он в режиме
186
      Другой метод реализации асинхронного ввода/вывода заключается в использова-
нии команд ReadFileEx() и WriteFileEx(). Вместо того чтобы сигнализировать о своем
завершении с помощью события, эти команды запускают специальную функцию, кото-
рая должна вызываться в конце каждой операции.
      Применение асинхронного ввода/вывода представляет собой стратегический при-
ем, позволяющий осуществлять работу с несколькими клиентами, подключенными к
различным экземплярам одного канала. Операции синхронного ввода/вывода проще
программировать, однако медленные команды записи и чтения часто задерживают вы-
полнение других операций. Сервер может создавать отдельный поток для каждого кли-
ента, однако такой подход подразумевает гораздо большую степень избыточности, чем
того требует реальная ситуация.
      При асинхронном вводе/выводе один и тот же поток может одновременно записы-
вать и читать данные в различных экземплярах канала, поскольку каждая из команд не-
медленно возвращает управление программе и освобождает поток, а операция вво-
да/вывода выполняется системой в фоновом режиме. С помощью команды
WaitForMultipleObjects() поток можно блокировать вплоть до завершения всех отложен-
ных операций. Эффективность асинхронного ввода/вывода особенно ярко проявляется
при медленных сетевых соединениях. Кроме того, при наличии меньшего числа синхро-
низируемых потоков гораздо проще обеспечить защиту программных ресурсов.
      В любой момент клиент может вызвать функцию CreateFile() для открытия сво-
его конца именованного канала. Однако при этом могут возникнуть две проблемы [12].
• Серверу иногда необходимо знать, подключился ли клиент к каналу. От операции
    записи в неподключенный канал пользы немного, и функция CreateFile() не сообща-
    ет серверу о наличии соединения.
• Если все экземпляры канала заняты, функция CreateFile() постоянно возвращает
    значение INVALID_HANDLE_VALUE, не устанавливая соединения. Клиент может
    подождать, пока не освободится один из экземпляров канала, где будет завершена
    операция, инициированная другим клиентом.
      Короче говоря, и сервер, и клиент должны иметь возможность блокироваться,
ожидая условий, при которых выполнение подключения станет возможным. Для этого
сервер должен вызвать функцию ConnectNamedPipe(), а клиент – функцию WaitNamed-
Pipe().

BOOL ConnectNamedPipe(
     HANDLE hNamedPipe,           // дескриптор доступного именованного канала
     LPOVERLAPPED lpOverlapped ); // поддержка асинхронного ввода/вывода

BOOL WaitNamedPipe(
     LPTSTR lpszPipeName,             // указывает на строку, которая задает
                                      // имя канала
      DWORD dwTimeout );       // максимальное время ожидания, миллисекунды

     Эти координирующие функции работают только с именованными каналами, по-
скольку клиент не может создавать собственных дескрипторов анонимных каналов, он
должен получить дескриптор непосредственно от сервера, а в этом случае подключение
уже выполнено.
     Подобно функциям ReadFile() и WriteFile(), функция ConnectNamedPipe() обеспе-
чивает асинхронную реакцию. Параметр lpOverlapped содержит дескриптор события,
которое будет служить сигналом об установке связи с клиентом.
     Функционирование команды ConnectNamedPipe() зависит от того, был ли канал
создан с указанием флага FILE_FLAG_OVERLAPPED и находится ли он в режиме

                                       186