Добавил:
СПбГУТ * ИКСС * Программная инженерия Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
АОПИ. Старое / АОПИ. Глава 2. Конспекты (02_04_19).rtf
Скачиваний:
65
Добавлен:
10.09.2019
Размер:
363.46 Кб
Скачать

Закрытие объекта ядра

Независимо от того, как именно Вы создали объект ядра, по окончании работы с ним его нужно закрыть вызовом CloseHandle:

BOOL CloseHandle(HANDLE hObject);

1. Эта функция сначала проверяет таблицу описателей, принадлежащую вызывающему процессу, чтобы убедиться, идентифицирует ли переданный ей индекс (описатель) объект, к которому этот процесс действительно имеет доступ. Если переданный индекс правильный, система получает адрес структуры данных объекта и уменьшает в этой структуре счетчик числа пользователей; как только счетчик обнулится, ядро удалит объект из памяти. Функция возратит TRUE.

2. Если же описатель неверен, происходит одно из двух. В нормальном режиме выполнения процесса CloseHandle возвращает FALSE, a GetLastError — код ERROR_INVALID_HANDLE. Но при выполнении процесса в режиме отладки система просто уведомляет отладчик об ошибке.

Перед самым возвратом управления CloseHandle удаляет соответствующую запись из таблицы описателей: данный описатель теперь недействителен в Вашем процессе и использовать его нельзя. При этом запись удаляется независимо от того, разрушен объект ядра или нет! После вызова CloseHandle Вы больше не получите доступ к этому объекту ядра; но, если его счетчик не обнулен, объект остается в памяти. Это означает лишь то, что объект используется другим процессом (или процессами). Когда и остальные процессы завершат свою работу с этим объектом (тоже вызвав CloseHandle), он будет разрушен.

Синхронизация объектов

Описатели объектов ядра зависимы от конкретного процесса (process specific). Иначе говоря, описатель объекта, полученный в одном процессе не имеет смысла в другом. Однако существуют способы работы с одними и теми же объектами ядра из разных процессов.

Наследование описателей объекта

При создании объекта можно указать, будет ли его описатель наследоваться дочерними (порожденными этим процессом) процессами.

Наследование применимо, когда процессы связаны родственными отношениями (родительский-дочерний). Например, родительскому процессу доступен один или несколько описателей объектов ядра, и он решает, породив дочерний процесс, передать ему по наследству доступ к своим объектам ядра.

Для наследования описателей объектов характерно одно очень странное свойство: дочерний процесс не имеет ни малейшего понятия, что он унаследовал какие-то описатели.

Для этого в дочерний процесс обычно передают значение ожидаемого им описателя объекта ядра как аргумент в командной строке. Инициализирующий код дочернего процесса анализирует командную строку, извлекает из нее значение описателя, и дочерний процесс получает неограниченный доступ к объекту. При этом механизм наследования срабатывает только потому, что значение описателя общего объекта ядра в родительском и дочернем процессах одинаково, — и именно по этой причине родительский процесс может передать значение описателя как аргумент в командной строке.

Существуют и другие формы межпроцессорной связи.

Именованные объекты

У некоторых объектов имеется строковый параметр Name. Он отвечает за имя объекта. Его можно установить в NULL (объект получиться безымянным), а можно присвоить ему какое-либо строковое значение.

Работа с именованным объектом.

1. Первый процесс создает именованный объект функцией Create??? (вместо ??? — какой-либо объект, допускающий именование).

HANDLE hMutexProcessA = CreateMutex(NULL, FALSE, "SpecMutex");

2. Второй процесс (может быть не дочерним по отношению к первому процессу!) исполняет тот же код.

HANDLE hMutexProcessA = CreateMutex(NULL, FALSE, "SpecMutex");