Вход/Регистрация
Параллельное и распределенное программирование на С++
вернуться

Хьюз Камерон

Шрифт:

Обратите внимание на то, что класс x_queue содержит к л асс мьютекс, т.е. между классами x_queue и мьютекс существует отношение агрегирования. Любая операция, которая изменяет состояние наше г о к л асса x_queue, может привести к «гонкам» данных, если, конечно, эгу операцию не синхронизировать. Следовательно, операции, которые добавляют объект в очередь или удаляют его из нее, являются кандидатами для синхронизации. В листинге 11.3 приведено объявление к л асса x_queue как шаблонного.

Рис.11.1. Отношения между потоками, PVM-задачами, очередью событий и классом pvm_stream в PVM-программе

Рис.11.2. Диаграмма классов для пользовательских классов x_queue и pvm_stream

// Листинг 11.3. Объявление класса x_queue

template <class T> x_queue class{

protected:

queue<T> EventQ;

mutex Mutex;

//...

public:

bool enqueue(T Object);

T dequeue(void);

//...

};

Метод enqueue используется для добавления элементов в очередь, а метод dequeue — для удаления их из очереди. Каждый из этих методов рассчитан на использование oбъeктaMutex. Определение этих методов приведено в листинге 11.4.

// Листинг 11.4. Определение методов enqueue и dequeue

tempIate<class T> bool x_queue<T>::enqueue(T Object)

{

Mutex.lock; EventQ.push(Object); Mutex.unlock;

}

Leinplr.te<class T> T x_queue<T>::dequeue(void)

{

T Object; //. . .

Mutex.lock;

Object = EventQ.front

EventQ.pop;

Mutex.unlock ;

//. . .

return(Object);

}

Теперь очередь может функционировать (принимать новые элементы и избавляться от ненужных) в многопоточной среде. ПотокВ (см. рис.11.1) добавляет элементы в очередь, а потокА удаляет их оттуда. Класс mutex является интерфейсным классом. Он заключает в оболочку функции pthread_mutex_lock , pthread_mutex_unlock , pthread_mutex_init и pthread_mutex_trylock. Класс x_queue также является интерфейсным, поскольку он адаптирует интерфейс для встроенного класса queue<T> . Прежде всего, он заменяет интерфейсы методов push и pop методами enqueue и dequeue . При этом операции вставки и удаления элементов из очереди заключаются между вызовами методов Mutex.lock и Mutex.unlock. Поэтому в первом случае мы используем интерфейсный класс для инкапсуляции переменных типа pthread_mutex_t* и pthread_mutexattr_t*, а также заключаем в интерфейсную оболочку несколько функций из библиотеки Pthread. А во втором случае мы используем интерфейсный класс для адаптации интерфейса класса queue<T>. Еще одно достоинство класса mutex состоит в том, что его легко использовать в других классах, которые содержат критические разделы или области.

Класс pvm_stream (см. рис. 11 1) также является критическим разделом, поскольку оба потока выполнения (А и В) имеют доступ к потоку данных. Опасность возникновения «гонок» данных здесь вполне реальна, поскольку потокА и поток В могут получить доступ к потоку данных одновременно. Следовательно, мы используем класс mutex в нашем классе pvm_stream для обеспечения необходимой синхронизации.

// Листинг 11.5. Объявление класса pvm_stream

class pvm_stream{

protected:

mutex Mutex;

int TaskId;

int MessageId;

// .
– -

public:

pvm_stream & operator <<(string X);

pvm_stream & operator «(int X);

pvm_stream &operator <<(float X);

pvm_stream &operator>>(string X);

//.. .

};

Как и в классе x_queue, объект Mutex используется применительно к функциям, которые могут изменить состояние объекта класса pvm_stream. Например, мы могли определить один из операторов "«" следующим образом .

// Листинг 11.6. Определение оператора << для

// класса pvm_stream

pvm_stream &pvm_stream::operator<<(string X) {

//...

pvm_pkbyte(const_cast<char *>(X.data),X.size,1);

Mutex.lock;

pvm_send(TaskId,MessageId);

Mutex.unlock;

//.. .

return(*this);

}

Класс pvm_stream использует объекты Mutex для синхронизации доступа к его критическому разделу точно так же, как это было сделано в классе x_queue. Важно отметить, что в обоих случалх инкапсулируются pthread_mutex-функции . Программист не должен беспокоиться о правильном синтаксисе их вызова. Здесь также используется более простой интерфейс для вызова функций lock и unlock . Более того, здесь нельзя перепутать, какую pthread_mutex_t*-nepeмeннyю нужно использовать с pthread_mutex-функциями. Наконец, программист может объявить несколько экземпляров класса mutex, не обращалсь снова и снова к функциям библиотеки Pthread. Раз мы сделали ссылку на Pthread-функции в определениях методов клlacca mutex, то теперь нам достаточно вызывать только эти методы.

Подробнее об объектно-ориентированном взаимном исключении и интерфейсных классах

Чтобы справиться со сложностью написания и поддержки программ с параллелизмом, попробуем упростить API-интерфейс с соответствующими библиотеками. В некоторых системах, возможно, имеет смысл создать библиотеки Pthreads, MPI, атакже стандартные функции использования семафоров и разделяемой памяти как часть единого решения. Все эти библиотеки и функции имеют собственные протоколы и синтаксис. Но у них есть много общего. Поэтому мы можем использовать интерфейсные классы, наследование и полиморфизм для создания упрощенного и непротиворечивого интерфейса, с которым непосредственно будет работать программист. Мы можем также скрыть от наших приложений детали реализации конкретной библиотеки. Если приложение опирается только на методы, используемые в наших интерфейсных классах, то оно будет защищено от изменений, вносимых в реализацию функций, обновлений библиотек и прочих «подводных» реструктуризации. В конце концов, работа над интерфейсом (интерфейсными классами) с компонентами параллелизма и библиотеками функций позволит существенно понизить уровень сложности параллельного программирования. Итак, рассмотрим подробнее, какие методы разработки интерфейсных классов можно реализовать для поддержки параллелизма.

  • Читать дальше
  • 1
  • ...
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: