Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
25
Добавлен:
17.04.2013
Размер:
99.33 Кб
Скачать

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

Часто возникает необходимость в доступе к объектам ядра нитями, принадлежащими разным процессам. Причин тому несколько:

• объекты «проекции файлов» позволяют двум процессам совместно использовать одни и те же области памяти;

• почтовые ящики (mail slots)и именованные каналы (named pipes)дают возможность программам обмениваться данными с процессами, исполняемыми на других машинах в сети;

• мьютексы (mutexes),семафоры (semaphores)и события (events)позволяют синхронизировать нити, исполняемые в разных процессах, так что одно приложение может уведомить другое об окончании той или иной операции.

Поскольку описатели объектов ядра имеют смысл только в контексте процесса, совместное использование объектов ядра между несколькими процессами в Win32 —задача весьма непростая.

Предусмотрены три механизма, позволяющие процессам совместно использовать одни и те же объекты ядра:

  • наследование описателей;

  • дублирование описателей;

  • использование именованных объектов

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

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

Чтобы такой сценарий наследования сработал, родительский процесс должен выполнить несколько операций.

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

Чтобы создать наследуемый описатель, родительский процесс выделяет и инициализирует структуру SECURITY_ATTRIBUTES,а затем передает ее адрес требуемой Createфункции. Следующий код создает наследуемый объект мьютекс с защитой по умолчанию и возвращает его описатель:

SECURITY_ATTRIBUTES sa sa.Length = siseof(sa); sa.lpSecurityDescnptor = NULL sa.bInheritHandle = TRUE HANDLE hMutex = CreateMutex(&sa, FALSE, NULL);

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

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

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

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

Еще один прием: родительский процесс добавляет в свой блок переменных окружения непустую переменную. Она должна быть «узнаваема» дочерним процессом и содержать значение наследуемого описателя объекта ядра. Далее родительский процесс создает дочерний, тот наследует переменные окружения родительского процесса и, вызвав GetEnvironmentVariable получает нужный описатель. Такой прием особенно хорош, когда дочерний процесс тоже порождает процессы, —ведь все переменные окружения вновь наследуются.

Соседние файлы в папке вар1