Что такое «технология COM» и как с ней бороться?№4
Курс молодого бойца
Будем считать, что
предыдущие
статьи вдохновили - технологию COM изучать
стоит. Что нужно, чтобы уверенно понимать о
чем дальше пойдет речь? Нужно знание
некоторых базовых концепций
программирования. Во-первых, следует хорошо
представлять себе понятия «процесс», «поток»
и «адресное пространство», а также
концепцию мультизадачности в операционной
системе. Весьма желательно знать, как
именно загружается DLL и создаётся новый
процесс в системе. Требуется в какой-то
достаточной мере знать концепции объектно-ориентированного
программирования, а для абсолютно
прозрачного понимания механизмов
технологии COM на нижнем уровне совершенно
необходимо неплохо представлять себе
конструкции, которые строит компилятор C++ в
объектном коде. Во-вторых, требуется
довольно четкое представление, что есть
вычислительная сеть - хотя бы на уровне
локальной сети, и представление каким
образом компьютеры взаимодействуют друг с
другом. В-третьих - требуется понимать
концепцию архитектуры «клиент-сервер».
Большинство понятий, которые
будут вводиться по ходу изложения будут
кратко комментироваться для тех читателей,
кто даже не знает как к ним подступиться и
будут даваться ссылки, где можно прочитать
о них подробнее и полнее. Более продвинутые
читатели эти места могут пропустить без
всяких потерь.
Начнем с концепции «клиент-сервер».
Это словосочетание с некоторых пор стало
привычным и связалось с контекстом доступа
к базам данных. Точнее, «для широкой публики»
оно стало означать «клиент - сервер базы
данных». Хотя на самом деле - это совсем не
так. Концепция «клиент-сервер» значительно
мощнее, чем принято об этом думать. Идея
концепции исходит из понятия «сервиса» -
некоторого действия, совершить которое
зачем-то требуется стороне A и которое она
сама выполнять не умеет. Зато стороне B
совершение этого действия не нужно, но как
раз она-то и умеет его совершать. В таком
случае сторона A каким-то образом вынуждает
сторону B совершить это действие и
предоставить стороне А результат. В таком
взаимодействии сторона, которая умеет
совершать действие, но не имеет никакой
инициативы его совершения называется «сервером»,
а сторона, которая состоит только из
инициативы - называется «клиентом». В этом
взаимодействии «клиент» запрашивает, а «сервер»
предоставляет «сервис».
Многие привычные случаи
программного взаимодействия можно
переосмыслить под этим углом, например
внутри обычной программы «вызывающая
процедура» очевидно является клиентом, а «вызываемая»
- сервером. Просто о них не принято думать в
таких терминах, хотя ничего некорректного в
этом нет. И во взаимодействии каких либо
машин, программ, объектов, когда один
запрашивает у другого совершить какое-либо
действие запрашивающий - всегда клиент, а
исполняющий - всегда сервер.
Понятия клиента и сервера -
динамические понятия. В диалоге объектов, т.е.
когда они вызывают друг-друга попеременно,
в разном взаимодействии каждый из них
попеременно будет и клиентом и сервером -
термин никоим образом не означает иной
специализации, чем это требуется для самого
взаимодействия.
Понятия «адресного пространства»,
«процесса», «потока» для тех, кто
программирует на C/C++ являются одними из
фундаментальных. Для программистов на VB
можно сказать следующее.
Программу исполняет процессор -
физическое устройство, которое одну за
одной, как они записаны в программе,
исполняет команды. Для программиста,
который мыслит безлично (для него просто «программа
исполняется») понятия процессора нет. Для
него есть понятие «поток передачи
управления», т.е. последовательность
прохождения команд программы. Но поток и
есть не что иное, как «внимание процессора»,
который выполняет последовательность
команд программы. Дело в том, что в машине
может быть более одного процессора, тогда,
либо одна программа могла бы выполняться в
несколько потоков, либо одновременно
машина могла бы выполнять несколько
программ. Последовательность выполнения
команд нарушать нельзя, поэтому конечно
дело не происходит так, что один процессор
выполняет «только чётные», а другой - «только
нечётные» строки программы. Для
возможности выполняться более, чем в одном
потоке, программа должна быть специально
сконструирована! А вот две независимые
программы каждую на своем процессоре -
выполнить можно, каждая из них будет
выполняться в своем потоке и ничего не
знать о других.
Процессом традиционно называют
совокупность всех ресурсов компьютера,
отданных операционной системой для
выполнения программы. Эти ресурсы включают
в себя внимание процессора, память, объекты
операционной системы и т.д. - важно понимать,
что процесс это не только текст
исполняющейся программы, но и всё, что она
для своего исполнения требует. Понятно, что
внутри процесса есть хотя бы один поток.
Когда системе предлагают программу «запустить
на исполнение» она создает один процесс и
один поток в котором и запускает программу.
Эффекта наличия в системе
нескольких процессоров можно достичь и не
имея их физически, а просто переключая
время от времени программы, исполняющиеся
на процессоре. Если квант времени, в течение
которого процессор занят одной программой,
не очень велик, то будет создаваться
иллюзия, что все программы исполняются
системой одновременно. В этом - суть
мультизадачности операционной системы.
Точное положение вещей состоит, конечно, в
том, что операционная система переключает
на процессоре не программы, а - потоки, как
вы теперь понимаете. О том же, но несколько
иными словами можно прочитать и тут.
Ну и наконец, программа для
своего исполнения требует памяти.
Совокупность всех доступных для программы
адресов памяти называется адресное
пространство. В ранних системах каждому
адресу соответствовал байт реальной памяти,
поэтому надобности в такой абстракции не
возникало - говорили просто «память». В
современных системах это далеко не так и
реальной памяти программа имеет куда
меньше, чем диапазон доступных ей адресов.
Почему и появилось такое понятие. Более
того, в современных системах память
устроена так, что по одному и тому же адресу
памяти доступному из программы,
расположены разные байты физической памяти
разных процессов. Т.е. абсолютно физически
невозможно одному процессу залезть в
память другого процесса - по какому бы
адресу он ни обращался, везде будет «его
собственная» память.
Очень подробно и доходчиво все
эти сложные концепции рассмотрены,
например, в книге Джеффри Рихтера «Windows для
профессионалов», и дальнейшие подробности
читатель может получить там.