Мегаобучалка Главная | О нас | Обратная связь  


ЭКЗАМЕНАЦИОННЫЙ БИЛЕТ № 6




1. Совместное использование объектов ядра несколькими процессами.

2. Критические секции и защита данных.

3. Анонимные каналы. Именованные каналы.

Анонимные каналы Win32 позволяют проводить одностороннее

(полудуплексное), символьно-ориентированное межпроцессное

взаимодействие. Каждый канал имеет два дескриптора: дескриптор чтения и

дескриптор записи. Для создания канала служит следующая функция

CreatePipe:

BOOL CreatePipe ( PHANDLE phRead, PHANDLE phWrite,

LPSECURITY_ATTRIBUTES lpsa, DWORD cbPipe)

Чтобы использовать канал для IPC, нужен еще один процесс, с которым

будет связан один из дескрипторов канала.

Чтение из дескриптора чтения канала блокируется, если канал пуст. В

противном случае считывается столько байтов, сколько имеется в канале, но не

превышая количества, указанного при вызове ReadFile. Также блокируется

операция записи в заполненный канал, который реализуется в буфере памяти.

Кроме всего прочего, анонимные каналы пропускают данные только в одну

сторону. Для двунаправленной связи нужны два канала.

Именованные каналы

Именованные каналы обладают рядом особенностей, которые делают их

удобным средством реализации приложений с использованием IPC.

Особенности именованных каналов (некоторые из них присутствуют не всегда)

перечислены ниже.

• Именованные каналы ориентированы на сообщения, так что читающий

процесс может читать сообщения переменной длины точно так, как они

передаются записывающим процессом.

• Именованные каналы двунаправлены, так что два процесса могут

обмениваться сообщениями по одному и тому же каналу.

• Может быть несколько независимых экземпляров именованного канала.

На пример, несколько клиентов могут связываться с одним сервером,

используя один и тот же канал, и сервер может ответить клиенту по тому

же экземпляру канала.

• К каналу по имени могут обращаться системы в сети. Связь через

именованный канал не зависит от того, работают ли оба процесса на одной

машине или на разных.

• Существует несколько функций-полуфабрикатов, упрощающих

взаимодействие по именованному каналу и соединение клиента с сервером.

Использование именованных каналов

Функция CreateNamedPipe создает первый экземпляр именованного

канала и возвращает его дескриптор. Также эта функция определяет

максимальное количество экземпляров канала и, следовательно, количество

клиентов, которых можно обслуживать одновременно.

Обычно процесс создания называется сервером. Процессы-клиенты,

возможно, работающие на других системах, открывают этот канал с помощью

CreateFile.

Создание именованных каналов

Ниже приведена функция CreateNamedPipe.

HANDLE CreateNamedPipe ( LPCTSTR lpszPipeName,

DWQRD fdwOpenMode, DWORD fdwPipeMode,

DWORD nMaxInstances, DWORD cbOutBuf,

DWORD cblnBuf, DWORD dwTimeOut,

LPSECURITY_ATTRIBUTES lpsa)

Параметры

lpszPipeName обозначает имя канала в форме: \\.\pipe\[путь]имя-канала

Точка обозначает локальную машину; иначе говоря, создать канал на

удаленной машине нельзя.

fdwOpenMode имеет одно из следующих значений:

- PIPE_ACCESS_DUPLEX — эквивалентно комбинации GENERIC_READ

и GENERIC_WRITE;

- PIPE_ACCESS_INBOUND — направление данных только от клиента к

серверу, эквивалентно GENERIC_READ;

- PIPE_ACCESS_OUTBOUND — эквивалентно GENERIC_WRITE.

Режим также может быть FILE_FLAG_WRITE_THROUGH (не используется

для каналов сообщений) и FILE_FLAG_OVERLAPPED.

fdwPipeMode может принимать три взаимоисключающих пары флагов.

Они указывают, является ли запись ориентированной на сообщения или

байтовой, осуществляется ли чтение по сообщениям или по блокам и

блокируется ли операция чтения.

- PIPE_TYPE_BYTE и PIPE_TYPE_MESSAGE, которые взаимно исключают

друг друга, указывают, записываются ли данные в канал как поток байтов

или как поток сообщений. Для всех экземпляров канала применяется один и

тот же тип.

- PIPE_READMODE_BYTE и PIPE_READMODE_MESSAGE указывают,

читаются ли данные как поток байтов или как поток сообщений. Для

PIPE_READMODE_MESSAGE необходимо PIPE_TYPE_MESSAGE.

- PIPE_WAIT и PIPE_NOWAIT определяют, будет ли операция ReadFile

блокироваться. Указывайте значение PIPE_WAIT, поскольку для

асинхронного ввода-вывода есть способы получше.

nMaxInstances определяет количество экземпляров канала и,

следовательно, количество одновременно обслуживаемых клиентов. Если

указать значение PIPE_UNLIMITED_ INSTANCES, количество каналов будет

определять ОС в зависимости от доступных системных ресурсов.

cbOutBuf и cbInBuf задают размеры в байтах буферов ввода и вывода,

используемых для именованных каналов. Если указать нуль, будут

использоваться значения по умолчанию.

dwTimeOut — принятый по умолчанию тайм-аут (в миллисекундах) для

функции WaitNamedPipe. Эта ситуация, в которой функция создания

определяет тайм-аут для другой функции, является уникальной.

Возвращаемое значение в случае ошибки — INVALID_HANDLE_VALUE,

так как дескрипторы каналов подобны дескрипторам файлов.

lpsa играет ту же роль, что и в других функциях создания.

При первом вызове CreateNamedPipe фактически создается именованный

канал, а не просто экземпляр. При закрытии последнего дескриптора

экземпляра сам этот экземпляр удаляется. Удаление последнего экземпляра

именованного канала вызывает удаление самого канала.

Подключение клиента к именованному каналу

Клиент может подключиться к именованному каналу с помощью вызова

CreateFile с указанием имени канала. Во многих случаях клиент и сервер

находятся на одной машине; тогда имя имеет вид: \\.\pipe\[путь]имя_канала

Если бы сервер находился на другой машине, имя выглядело бы так:

\\имя_сервера\pipe\[путь]имя_канала

Если сервер локальный, то применение для имени символа "." вместо

указания имени самой машины значительно повышает быстродействие.

Функции состояния именованного канала

GetNamedPipeHandleState возвращает для данного открытого

дескриптора сведения о том, находится ли канал в блокируемом или

неблокируемом режиме, ориентирован ли он на сообщения или на байты, о

количестве экземпляров канала и т.д.

SetNamedPipeHandleState позволяет программе задавать эти атрибуты

состояния.

GetNamedPipelnfo определяет, связан ли дескриптор с клиентом или

сервером, каков размер буфера и т.д.

Функции подключения именованного канала

После создания экземпляра именованного канала сервер может отслеживать

подключение клиента (с помощью функций CreateFile или CallNamedPipe),

используя функцию ConnectNamedPipe.

BOOL ConnectNamedPipe ( HANDLE hNamedPipe,

LPOVERLAPPED lpo)

Если задать в lpo значение NULL, выполнение ConnectNamedPipe

завершится сразу же, как только появится подключение клиента. Обычно

функция возвращает TRUE. Значение FALSE может быть, если клиент

подключается между вызовами сервером функций CreateNamedPipe и

ConnectNamedPipe. В этом случае GetLastError возвращает значение

ERROR_PIPE_CONNECTED.

После возвращения из ConnectNamedPipe сервер может читать запросы с

помощью ReadFile и записывать ответы, используя WriteFile. В заключение

сервер должен вызвать функцию DisconnectNamedPipe, чтобы освободить

дескриптор (экземпляр канала) для соединения с другим клиентом.

Последняя функция, WaitNamedPipe, предназначена для синхронизации

подключений клиента. Эта функция завершается, если на сервере имеется

незавершенное обращение к ConnectNamedPipe. Используя

WaitNamedPipe, клиент может убедиться, что сервер готов к подключению,

после чего вызвать CreateFile. Кроме того, вызов сервером функции

ConnectNamedPipe в этом случае завершится успешно.

Соединение клиента и сервера через именованный канал

Сначала в последовательности сервера осуществляется подключение

клиента, с которым сервер связывается до тех пор, пока тот не разорвет

соединение, затем сервер закрывает подключение на стороне сервера и

соединяется с другим клиентом.

Далее приводится последовательность подключения клиента, в которой

клиент закрывается, когда завершает работу, позволяя другому клиенту

соединиться через тот же экземпляр именованного канала. Клиент может

соединяться с сервером через сеть, если ему известно имя сервера.

Обратите внимание, что между клиентом и сервером происходит состязание.

Во-первых, вызов клиентом WaitNamedPipe завершится неудачно, если

сервер еще не создал именованный канал. Во-вторых, возможны

обстоятельства, в которых клиент может завершить свой вызов CreateFile

прежде, чем сервер вызовет ConnectNamedPipe. В этом случае

ConnectNamedPipe возвратит FALSE, но связь через именованный канал

будет работать, как положено.

Транзакционные функции именованного канала

Клиент выполняет следующее:

• открывает экземпляр канала, создавая долговременное подключение к

серверу и потребляя этот экземпляр канала;

• попеременно посылает запросы и ожидает ответов;

• закрывает подключение.

Обычную последовательность функций WriteFile, ReadFile можно

считать отдельной транзакцией клиента, и в Win32 имеется такая функция для

каналов сообщений.

BOOL TransactNamedPipe ( HANDLE hNamedPipe,

LPVOID lpvWriteBuf, DWORD cbWriteBuf,

LPVOID lpvReadBuf, DWORD cbReadBuf,

LPDWORD lpcbRead, LPOVERLAPPED lpa)

Назначение параметров не нуждается в объяснении, так как эта функция

представляет собой сочетание WriteFile и ReadFile для дескриптора

именованного канала. Указываются как выходной, так и входной буферы, а

*lpcbRead задает длину сообщения.

Функция TransactNamedPipe удобна, но требует постоянного

подключения, что ограничивает число клиентов.

CallNamedPipe, вторая функция-полуфабрикат, лишена этого недостатка,

так как объединяет в себе всю последовательность: CreateFile, WriteFile,

ReadFile, CloseHandle.

Преимущество заключается в более эффективном использовании канала,

несмотря на издержки подключения при каждом запросе.

BOOL CallNamedPipe ( LPCPSTR lpszPipeName,

LPVOID lpvWriteBuf, DWORD сbWriteBuf,

LPVOID lpvReadBuf, DWORD сbReadBuf,

LPDWORD lpcbRead, DWORD dwTimeOut)

Использование параметров подобно TransactactNamedPipe с тем

исключением, что для канала указывается имя, а не дескриптор. Функция

CallNamedPipe является синхронной.

Здесь также указывается тайм-аут в миллисекундах — для подключения, но

не для транзакции. Для dwTimeOut существует также три специальных

значения:

• NMPWAIT_NOWAIT;

• NMPWAIT_WAIT_FOREVER;

• NMPWAIT_USE_DEFAULT_WAIT — в этом случае используется тайм-аут

по умолчанию, заданный при вызове CreateNamedPipe.

Наблюдение за сообщениями в именованном канале

Кроме чтения именованного канала с помощью ReadFile, можно также

определять, присутствует ли в нем сообщение, которое можно считать. Для

этого служит функция PeekNamedPipe.

BOOL PeekNamedPipe (HANDLE hPipe, LPVOID lpvBuffer,

DWORD cbBuffer, LPDWQRD lpcbRead,

LPDWORD lpcbAvail, LPDWORD lpcbMessage)

Функция PeekNamedPipe читает все байты или сообщения в канале, не

разрушая их; она не блокируется и завершается немедленно.

Чтобы узнать, есть ли данные в канале, проверьте значение *lpcbAvail;

если есть, *lpcbAvail будет больше нуля. В этом случае lpvBuffer и

lpcbRead могут иметь значение NULL. Е СЛИ буфер задан параметрами

lpvBuffer и cbBuffer, то *lpcbMessage сообщает, есть ли оставшиеся байты

сообщения, которые не вписываются в буфер, что позволяет выделить большой

буфер перед чтением из именованного канала. В байтовом режиме канала это

значение нулевое.

Еще раз подчеркнем, что PeekNamedPipe не уничтожает сообщения, так

что для удаления сообщений или байтов из канала нужен дополнительный

вызов ReadFile.

Безопасность именованного канала

Ниже приведены важные права безопасности для именованных каналов.

• GENERIC_READ.

• GENERIC_WRITE.

• SYNCHRONIZE (разрешает ожидание потока).

Соответствующие права устанавливаются в зависимости от режима доступа

(дуплексный, входящий или исходящий). Для всех трех режимов требуется

право SYNCHRONIZE.

 

 




Читайте также:
Как вы ведете себя при стрессе?: Вы можете самостоятельно управлять стрессом! Каждый из нас имеет право и возможность уменьшить его воздействие на нас...
Как выбрать специалиста по управлению гостиницей: Понятно, что управление гостиницей невозможно без специальных знаний. Соответственно, важна квалификация...
Как построить свою речь (словесное оформление): При подготовке публичного выступления перед оратором возникает вопрос, как лучше словесно оформить свою...



©2015-2020 megaobuchalka.ru Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. (349)

Почему 1285321 студент выбрали МегаОбучалку...

Система поиска информации

Мобильная версия сайта

Удобная навигация

Нет шокирующей рекламы



(0.006 сек.)