Параллельное и распределенное программирование на С++ (Хьюз, Хьюз) - страница 277

>mpi_stream Stream1;

>mpi_stream Stream2;

>Streaml << Messagel << Message2 << Message3;

>Stream2 >> Message4;

>//. . .

Нри таком подходе программист может целиком сосредоточиться на логике программы и не ломать голову над соблюдением требований к синтаксису библиотеки MPI.

Как воспользоваться преимуществами интерфейсных классов

Зачастую полезно использовать инкапсуляцию, чтобы скрыть детали библиотек функций и обеспечить создание самодостаточных компонентов, которые годятся для многократного использования. Возьмем для примера мьютекс, который мы рассматривали в главе 7. Вспомним, что мьютекс— это переменная специального типа, ис-пользуемая для синхронизации. Мьютексы позволяют получать безопасный доступ к критическом) разделу данных или кода программы. Существует шесть основных функций, предназначенных для работы с переменной типа pthread_mutex_t (POSIX Threads Mutex).

Все эти функции принимают в качестве параметра указатель на переменную типа pthread_mutex_t. Для инкапсуляции доступа к переменной типа pthread_mutex_t и упрощения вызовов функций, которые обращаются к мьютексным переменным, можно использовать интерфейсный класс. Рассмотрим листинг 11.1, в котором объявляется класс mutex.

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

class mutex{ protected:

pthread_mutex_t *Mutex;

pthread_mutexattr_t *Attr; public:

mutex(void)

int lock(void);

int unlock(void);

int trylock(void);

int timedlock(void);

};

Объявив класс mutex, используем его для определения мьютексных пере м енных. Мы можем объявлять массивы мьютексов и использовать эти пере м енные как члены пользовательских классов. Инкапсулировав пере м енную типа • pthread_mutex_t и мьютексные функции, воспользуемся преимуществами методов объектно-ориентированного программирования. Эти мьютексные переменные можно затем применять в качестве аргументов функций и значений, возвра щ аемых функциями. А поскольку мьютексные функции теперь связаны с переменной типа pthread_mutex_t, то там, где мы используем мьютексную переменную, эти функции также будут доступны.

Функции-члены класса mutex определяются путем заключения в оболочку вызовов соответствующих Pthread-функций, например, так.

// Листинг 11.2. Функции-члены класса mutex

mutex::mutex(void) {

try{

int Value;

Value = pthread_mutexattr_int(Attr); //. . .

Value = pthread_mutex_init(Mutex,Attr); //. . .

\

}

int mutex::lock(void) {

int RetValue;

RetValue = pthread_mutex_lock(Mutex); //. . .

return(ReturnValue);

}

Благодаря инкапсуляции мы также защищаем переменные типа pthread_mutex_t * и