Программа-пример Optex
Эта программа, "10 Optex.exe" (см.листинг на рис, 10-1), предназначенадля проверки того, что класс COptex работает корректно. Файлы исходного кода и ресурсов этой программы находятся в каталоге 10-Optex на компакт-диске, прилагаемом к книге. Я всегда запускаю такие приложения под управлением отладчика, чтобы наблюдать за всеми функциями и переменными — членами классов.
При запуске программа сначала определяет, является ли она первым экземпляром. Для этого я создаю именованный объект ядра "событие". Реально я им не пользуюсь, а просто смотрю, вернет ли GetLastError значение ERROR_ALREADY_EXISTS. Если да, значит, это второй экземпляр программы. Зачем мне два экземпляра этой программы, я объясню позже.
Если же это первый экземпляр, я создаю однопроцессный объект COptex и вызываю свою функцию FirstFunc. Она выполняет серию операций с объектом-оптексом и создает второй поток, который манипулирует тем же оптексом. На этом этапе с оптексом работают два потока из одного процесса. Что именно они делают, Вы узнаете, просмотрев исходный код. Я пытался охватить все мыслимые сценарии, чтобы дать шанс на выполнение каждому блоку кода в классе COptex.
После тестирования однопроцессного оптекса я начинаю проверку межпроцессного оптекса. В функции _tWinMain по завершении первого вызова FirstFunc я создаю другой объект-оптекс COptex. Но на этот раз я присваиваю ему имя — CrossOptexTest. Простое присвоение оптексу имени в момент создания превращает этот объект в межпроцессный. Далее я снова вызываю FirstFunc, передавая сй адрес межпроцессного оптекса. При этом FirstFunc выполняет в основном тот же код, что и раньше. Но теперь она порождает не второй поток, а дочерний процесс.
Этот дочерний процесс представляет собой всего лишь второй экземпляр той же программы. Однако, создав при запуске объект ядра "событие", она обнаруживает, что такой объект уже существует. Тем самым она узнает, что является вторым экземпляром, и выполняет другой код (отличный от того, который выполняется первым экземпляром). Первое, что делает второй экземпляр, — вызывает DebugBreak:
VOID DebugBreak();
Эта удобная функция инициирует запуск отладчика и его подключение к данному процессу. Это здорово упрощает мне отладку обоих экземпляров данной программы. Далее второй экземпляр создает межпроцессный оптекс, передавая конструктору строку с тем же именем. Поскольку имена идентичны, оптекс становится разделяемым между обоими процессами. Кстати, один оптекс могут разделять более двух процессов.
Наконец, второй экземпляр программы вызывает функцию SecondFunc, передавая сй адрес межпроцессного оптекса, и с этого момента выполняется тот же набор тестов. Единственное, что в них меняется, — два потока, манипулирующие оптексом, принадлежат разным процессам.
Optex