-->

Параллельное и распределенное программирование на С++

На нашем литературном портале можно бесплатно читать книгу Параллельное и распределенное программирование на С++, Хьюз Камерон-- . Жанр: Программирование / Программное обеспечение / Прочая компьютерная литература. Онлайн библиотека дает возможность прочитать весь текст и даже без регистрации и СМС подтверждения на нашем литературном портале bazaknig.info.
Параллельное и распределенное программирование на С++
Название: Параллельное и распределенное программирование на С++
Дата добавления: 16 январь 2020
Количество просмотров: 420
Читать онлайн

Параллельное и распределенное программирование на С++ читать книгу онлайн

Параллельное и распределенное программирование на С++ - читать бесплатно онлайн , автор Хьюз Камерон

В книге представлен архитектурный подход к распределенному и параллельному программированию с использованием языка С++. Здесь описаны простые методы программирования параллельных виртуальных машин и основы разработки кластерных приложений. Эта книга не только научит писать программные компоненты, предназначенные для совместной работы в сетевой среде, но и послужит надежным «путеводителем» по стандартам для программистов, которые занимаются многозадачными и многопоточными приложениями. Многолетний опыт работы привел авторов книги к использованию агентно-ориентированной архитектуры, а для минимизации затрат на обеспечение связей между объектами системы они предлагают применить методологию «классной доски».Эта книга адресована программистам, проектировщикам и разработчикам программных продуктов, а также научным работникам, преподавателям и студентам, которых интересует введение в параллельное и распределенное программирование с использованием языка С++.

Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала

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

Архитектура «классной доски» служит прекрасным примером структуры, которая может использовать преимущества «мьютексов считывания» и мьютексов более общего назначения. Под «классной доской» понимается область памяти, разделяемал параллельно выполняемыми задачами. «Классная доска» используется для хранения решений некоторой проблемы, которую совместными усилиями решает целая группа задач. По мере приближения задач к решению проблемы каждая из них записывает результаты на «классную доску» и просматривает ее содержимое с целью поиска результатов, сгенерированных другими задачами, которые могут оказаться полезными для нее. Структура «классной доски» является критическим разделом. В действительности мы хотим, чтобы одновременно только одна задача могла обновлять содержимое «классной доски». Однако ее одновременное считывание мы можем позволить любому количеству задач. Кроме того, если несколько задач уже считывает содержимое «классной доски», нам нужно, чтобы оно не начало обновляться до тех пор, пока все эти задачи не завершат чтение. «Мьютекс считывания» как раз подходит для такой ситуации, поскольку он может управлять доступом к «классной доске», разрешал его только считывающим задачам и запрещал его для записывающих задач. Но если решение проблемы будет найдено, содержимое «классной доски» необходимо обновить. В процессе обновления нам нужно, чтобы ни одна считывающал задача не получила доступ к критическому разделу. Мы хотим заблокировать доступ для чтения до тех пор, пока не завершит обновление записывающал задача. Следовательно, нам нужно создать «мьютекс записи». В любой момент времени удерживать этот «мьютекс записи» может только одна задача. Поэтому мы делаем различие между мьютексом, который блокируется для считывания, но не для записи, и мьютексом, который блокируется для записи, но не для считывания. С использованием мьютекса считывания у нас может быть несколько параллельных считывающих задач, а с использованием мьютекса записи — только одна записывающал задача. Описаннал схема является частью модели CREW (Concurrent Read Exclusive Write — параллельное чтение, монопольнал запись) параллельного программирования.

Для разработки спецификации нашего мьютексного класса нам нужно наделить его способностью выполнять блокировки считывания и блокировки записи. В библиотеке Pthreads предусмотрены мьютексные переменные блокировки чтения-записи и атрибутов:

pthread_rwlock_t и pthread_rwlockattr_t

Эти переменные используются совместно с 11ю pthread_rwlock()-функциями. Мы используем наш интерфейсный класс rw_mutex для инкапсуляции переменных pthread_rwlock_t и pthread_rwlockattr_t, а также для заключения в оболочку Pthread-функций мьютексной организации чтения-записи.

Синопсис

#include <ptrhead.h>

int pthread_rwlock_init(pthread_rwlock_t *,const pthread_rwlockattr_t *);

int pthread_rwlock_destroy(pthread_rwlock_t *) ;

int pthread_rwlock_rdlock(pthread_rwlock_t *);

int pthread_rwlock_tryrdlock(pthread_rwlock_t *);

int pthread_rwlock_wrlock(pthread_rwlock_t *);

int pthread_rwlock_trywrlock(pthread_rwlock_t *);

int pthread_rwlock_unlock(pthread_rwlock_t *);

int pthread_rwlockattr_init(pthread_rwlockattr_t *);

int pthread_rwlockattr_destroy(pthread_rwlockattr_t *);

int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *,int *);

int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *, int) ;

// Листинг 11.9. Объявление класса rw_mutex, который

// содержит объекты типа pthread_rwlock_ t

// и pthread_rwlockattr_t

class rw_mutex : public mutex{

protected:

struct pthread_rwlock_t *RwLock;

struct pthread_rwlockattr_t *RwLockAttr;

public:

//.. .

int read_lock(void);

int write_lock(void);

int try_readlock(void);

int try_writelock(void);

//.. .

};

Класс rw_mutex наслелует класс mutex. На рис. 11.3 показаны отношения между классами rw_mutex, mutex, synchronization_variable и runtime_error.

Рис. 11.3. Отношения между классами rw_mutex, mutex, synchronization_variable и runtime_error

Пока мы создаем «узкий» интерфейс. На данном этапе мы заинтересованы в обеспечении минимального набора атрибутов и характеристик, необходимых для обобщения нашего класса mutex с использованием мьютексных типов и функций из библиотеки Pthread. Но после создания «узкого» интерфейса для класса mutex мы воспользуемся им как основой для создания «полуширокого» интерфейса. «Узкий» интерфейс обычно применяется в отношении классов, которые связаны наследованием. «Широкие» интерфейсы, как правило, применяют к классам, которые связаны функциями, а не наследованием. Нам нужен интерфейсный класс для упрощения работы с классами или функциями, которые принадлежат различным библиотекам, но выполняют подобные действия. Интерфейсный класс должен обеспечить программиста удобными рабочими инструментами. Для этого мы берем все библиотеки или классы с подобными функциями, отбираем все общие функции и переменные и после некоторого обобщения помещаем их в большой класс, который содержит все требуемые функции и атрибуты. Так определяется класс с «широким» интерфейсом. Но если включить в него (например, в класс rw_mutex) только интересующие нас функции и данные, мы получим «полуширокий» интерфейс. Его преимущества перед «широким» интерфейсом заключаются в том, что он позволяет нам получать доступ к объектам, которые связаны лишь функционально, и ограничивает множество методов, которыми может пользоваться программист, теми, которые содержатся в интерфейсном классе с узким «силуэтом». Это может быть очень важно при интеграции таких больших библиотек функций, как MPI и PVM с POSIX-возможностями параллелизма. Объединение MPI-, PVM- и POSIX-средств дает сотни функций с аналогичными целями. Затратив время на упрощение этой функциональности в интерфейсных классах, вы позволите программисту понизить уровень сложности, связанный с параллельным и распределенным программированием. Кроме того, эти интерфейсные классы становятся компонентами, которые можно многократно использовать в различных приложениях.

Чтобы понять, как подойти к созданию «полуширокого» интерфейса, построим интерфейсный класс для POSIX-семафора. И хотя семафор не является частью библиотеки Pthread, он находит аналогичные применения в многопоточной среде. Его можно использовать в среде, которая включает параллельно выполняемые процессы и потоки. Поэтому в некоторых случалх требуется объект синхронизации более общего характера, чем наш класс mutex.

Определение класса semaphore показано в листинге 11.10.

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

class semaphore : public synchronization_variable( protected:

sem_t * Semaphore; public://.. .

int lock(void);

int unlock(void);

int trylock(void);

//. . .

};

Синопсис

<semaphore.h>

int sem_init(sem_t *, int, unsignedint) ;

int sem_destroy(sem_t *);

sem_t *sem_open(const char *, int, ...);

int sem_close(sem_t *);

int sem_unlink(const char *);

int sem_wait(sem_t *);

int sem_trywait(sem_t *);

int sem_post(sem_t *);

int sem_getvalue(sem__t *, int *);

Обратите внимание на то, что класс semaphore имеет такой же интерфейс, как и наш класс mutex. Чем же они различаются? Хотя интерфейсы классов mutex и semaphore одинаковы, реализация функций lock (), unlock (), trylock () и тому подобных представляет собой вызовы семафорных функций библиотеки POSIX .

// Листинг 11.11. Определение методов lock(), unlock() и

// trylock() для класса semaphore

int semaphore::lock(void) (

//.. .

return(sem_wait(Semaphore));

}

int semaphore::unlock(void) {

Перейти на страницу:
Комментариев (0)
название