Составители:
Другой метод реализации асинхронного ввода/вывода заключается в использова-
нии команд 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
Страницы
- « первая
- ‹ предыдущая
- …
- 182
- 183
- 184
- 185
- 186
- …
- следующая ›
- последняя »