На основе объектной технологии
становится проще разрабатывать системы
с высоким уровнем параллелизма. Объект
можно представить как некоторую обособленную
сущность, взаимодействие с которой осуществляется
с помощью объявленного интерфейса. Инкапсуляция
защищает область данных объекта от случайного
или умышленного изменения. Как следствие,
несколько объектов могут работать параллельно,
избегая негативного влияния друг на друга.
Это действительно возможно, если правильно
реализовать взаимодействие между объектами.
В частности, надо избегать прямых или
косвенных обращений к свойствам объектов
(вызовов методов), отдавая предпочтение
взаимодействию на основе сообщений. Говоря
общими терминами, можно сказать, что синхронную
форму связи желательно заменять асинхронной.
При синхронном режиме взаимодействия управление
передаётся тому объекту и тому свойству,
к которым обращаются. Возврат управления
происходит после того, как свойство завершило
работу. Асинхронное взаимодействие не
забирает управление у того объекта, который
произвёл вызов. Вызывающий объект после
асинхронного обращения продолжает работу.
Свойство объекта может возвращать
или не возвращать результаты. При синхронной
связи результат работы вызванного свойства
передаётся в момент возврата управления.
При асинхронной связи результат возвращается
в некоторую точку синхронизации. Если
расположить точку синхронизации непосредственно
за асинхронным обращением, то результат
будет аналогичен синхронному обращению.
То есть, синхронное обращение к свойству
объекта можно считать частным случаем
асинхронного обращения.
Обычно синхронные обращения
ассоциируются с прямыми или косвенными
вызовами подпрограмм, в то время как асинхронные
обращения, отождествляют с обменом сообщениями.
На самом деле это не более чем удобные
метафоры, и именно в силу своего удобства
и простоты восприятия они и будут использоваться
при дальнейшем изложении.
Синхронные вызова подпрограмм
считаются более быстрыми и экономичными
формами связи по сравнению с асинхронной
передачей сообщений. Однако такое утверждение
справедливо далеко не всегда. При последовательном
режиме работы вызов подпрограммы действительно
происходит и быстро, и экономично, например,
он сведётся к следующему набору операторов:
push |
param1 |
|
push |
param2 |
|
... |
|
|
push |
paramN |
|
call |
MyProc |
; прямой вызов |
или |
|
|
push |
param1 |
|
push |
param2 |
|
... |
|
|
push |
paramN |
|
call |
call [eax * 4
+ VirtualTable] |
; косвенный вызов |
... |
|
|
|
Но с переходом к параллельному
исполнению, утверждение о более быстрой
форме синхронных вызовов может утратить
свою силу. Чтобы понять, почему так происходит,
достаточно привести простой пример. Рассмотрим
работу участкового врача. Пусть у него
на попечении находится всего один больной.
Приняв вызов от пациента, врач отправляется
к нему на дом, и производит осмотр или
другие медицинские процедуры. Эта схемы
работы оптимальна. Теперь увеличим число
больных. Если врач по-прежнему будет ходить
на каждый вызов, то первых пациентов он,
возможно, обслужит быстро, чего нельзя
сказать про остальных. Здесь будет более
удобна другая форма обслуживания. Врач,
получив несколько вызовов, оптимизирует
маршрут обхода и только после этого начинает
посещения больных. Экономия времени и
сил врача происходит не только за счёт
того, что он не возвращается за каждым
новым вызовом в поликлинику, но и за счёт
того, что минимизировано расстояние до
каждого следующего пациента.
|