Читаем Объектно-ориентированный анализ и проектирование с примерами приложений на С++ полностью

При разработке любого универсального инструментального средства должны учитываться проблемы, связанные с организацией параллельных процессов. В операционных системах типа UNIX, OS/2 и Windows NT приложения могут запускать несколько "легких" процессов ["Легким" называется процесс, который исполняется в том же адресном пространстве, что и другие. В противоположность им существуют "тяжелые" процессы; их создает, например, функция fork в UNIX. Тяжелые процессы требуют специальной поддержки операционной системы для организации связи между собой. Для C++ библиотека AT&T предлагает "полупереносимую" абстракцию легких процессов для UNIX. Легкие процессы непосредственно доступны в OS/2 и Windows NT. В библиотеку классов Smalltalk включен класс Process, реализующий поддержку легких процессов]. В большинстве случаев классы просто не смогут работать в такой среде без специальной доработки: когда две задачи взаимодействуют с одним и тем же объектом, они должны делать это согласованно, чтобы не разрушить состояния объекта. Как уже отмечалось, существуют два подхода к задаче управления процессами; они находят свое отражение в существовании защищенной и синхронизированной форм класса.

При разработке данной библиотеки было сделано следующее предположение: разработчики, планирующие использовать параллельные процессы, должны импортировать либо разработать сами по крайней мере класс Semaphore (семафор) для синхронизации легких процессов. Разработчики, которые не хотят связываться с параллельными процессами, будут свободны от необходимости поддерживать защищенные или синхронизованные формы классов (таким образом, не потребуется никаких дополнительных издержек). Защищенные и синхронизированные формы изолированы в библиотеке и основываются на своей внутренней реализации параллелизма. Единственная зависимость от локальной реализации сосредоточена в классе Semaphore, который имеет следующий интерфейс:

class Semaphore {public:

Semaphore();Semaphore(const Semaphore&);Semaphore(unsigned int count);~Semaphore();void seize(); // захватитьvoid release(); // освободитьunsigned int nonePending() const;

protected:};

Так же, как и при управлении памятью, мы разделяем политику синхронизации процессов и ее реализацию. По этой причине в аргументы шаблона для каждой защищенной формы включен класс Guard (страж), ответственный за связь с локальной реализацией класса Semaphore или его эквивалента. Аргументы шаблона для каждой из синхронизированных форм содержат класс Monitor, который близок по своим функциональным свойствам к классу Semaphore, но, как будет видно в дальнейшем, обеспечивает более высокий уровень параллелизма процессов.

Как показано на рис. 9-3, защищенный класс является прямым подклассом своего конкретного ограниченного либо неограниченного класса и содержит в себе объект класса Guard. Все защищенные классы имеют общедоступные функции-члены seize (захватить) и release (освободить), позволяющие получить эксклюзивный доступ к объекту. Рассмотрим в качестве примера класс GuardedUnboundedQueue, производный от UnboundedQueue:

template class GuardedUnboundedQueue : public UnboundedQueue { public:

GuardedUnboundedQueue(); virtual ~GuardedUnboundedQueue(); virtual void seize(); virtual void release();

protected:

Guard guard;

};

В нашей библиотеке предусмотрен интерфейс одного из предопределенных классов защиты: класса semaphore. Пользователи могут дополнить реализацию данного класса в соответствии с локальным определением легкого процесса.

На рис. 9-10 приведена схема работы данного варианта синхронизации; клиенты, использующие защищенные объекты, должны придерживаться простого алгоритма: сначала захватить объект для эксклюзивного доступа, провести над ним нужную работу, и после ее окончания снять защиту (в том числе в тех случаях, когда возникла исключительная ситуация). Другая схема поведения рассматривается как социально неприемлемая, поскольку претензии одного агента не позволят правильно работать другим. Если мы, например, не снимем защиту после окончания работы с объектом, больше никто не сможет получить к нему доступ; попытка снятия защиты с объекта, к которому в данный момент никто не имел эксклюзивного доступа, также может привести к нежелательным последствиям. Игнорирование этого протокола просто безответственно, поскольку оно может разрушить состояние объекта, с которым одновременно работают несколько агентов.  

Рис. 9-10. Процессы защищенного механизма.

Перейти на страницу:

Похожие книги

Adobe Flash. Создание аркад, головоломок и других игр с помощью ActionScript
Adobe Flash. Создание аркад, головоломок и других игр с помощью ActionScript

Данная книга посвящена программированию игр с помощью ActionScript. Здесь вы найдете подробные указания, необходимые для создания самых разных игр – аркад, головоломок, загадок и даже игровых автоматов. В тексте приведены исходные коды программ и детальные, доступно изложенные инструкции. Базовые принципы программирования ActionScript рассматриваются на примере игр, однако вы без труда сможете применить полученные знания и для разработки неигровых проектов, таких как Web-дизайн и реклама. Рекомендации Гэри Розенцвейга помогут вам не только придумывать занимательные игры и размещать их на Web-сайте, но и оптимизировать скорость их работы, а также защищать свои творения от несанкционированного копирования. Представленный в книге код несложно изменить для использования в других программах.Книга предназначена для широкого круга читателей – создателей анимационных роликов, художников-оформителей, программистов и разработчиков Web-сайтов. Издание может также выступать в качестве практического пособия по изучению ActionScript.

Гэри Розенцвейг

Программирование, программы, базы данных / Программирование / Книги по IT