Теперь очередь может функционировать (принимать новые элементы и избавляться от ненужных) в многопоточной среде. ПотокВ (см. рис.11.1) добавляет элементы в очередь, а потокА удаляет их оттуда. Класс
Класс 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
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, то теперь нам достаточно вызывать только эти методы.
Подробнее об объектно-ориентированном взаимном исключении и интерфейсных классах