MyBooks.club
Все категории

Олег Цилюрик - QNX/UNIX: Анатомия параллелизма

На сайте mybooks.club вы можете бесплатно читать книги онлайн без регистрации, включая Олег Цилюрик - QNX/UNIX: Анатомия параллелизма. Жанр: Программное обеспечение издательство -,. Доступна полная версия книги с кратким содержанием для предварительного ознакомления, аннотацией (предисловием), рецензиями от других читателей и их экспертным мнением.
Кроме того, на сайте mybooks.club вы найдете множество новинок, которые стоит прочитать.

Название:
QNX/UNIX: Анатомия параллелизма
Издательство:
-
ISBN:
-
Год:
-
Дата добавления:
16 сентябрь 2019
Количество просмотров:
359
Читать онлайн
Олег Цилюрик - QNX/UNIX: Анатомия параллелизма

Олег Цилюрик - QNX/UNIX: Анатомия параллелизма краткое содержание

Олег Цилюрик - QNX/UNIX: Анатомия параллелизма - описание и краткое содержание, автор Олег Цилюрик, читайте бесплатно онлайн на сайте электронной библиотеки mybooks.club
Книга адресована программистам, работающим в самых разнообразных ОС UNIX. Авторы предлагают шире взглянуть на возможности параллельной организации вычислительного процесса в традиционном программировании. Особый акцент делается на потоках (threads), а именно на тех возможностях и сложностях, которые были привнесены в технику параллельных вычислений этой относительно новой парадигмой программирования. На примерах реальных кодов показываются приемы и преимущества параллельной организации вычислительного процесса. Некоторые из результатов испытаний тестовых примеров будут большим сюрпризом даже для самых бывалых программистов. Тем не менее излагаемые техники вполне доступны и начинающим программистам: для изучения материала требуется базовое знание языка программирования C/C++ и некоторое понимание «устройства» современных многозадачных ОС UNIX.В качестве «испытательной площадки» для тестовых фрагментов выбрана ОСРВ QNX, что позволило с единой точки зрения взглянуть как на специфические механизмы микроядерной архитектуры QNX, так и на универсальные механизмы POSIX. В этом качестве книга может быть интересна и тем, кто не использует (и не планирует никогда использовать) ОС QNX: программистам в Linux, FreeBSD, NetBSD, Solaris и других традиционных ОС UNIX.

QNX/UNIX: Анатомия параллелизма читать онлайн бесплатно

QNX/UNIX: Анатомия параллелизма - читать книгу онлайн бесплатно, автор Олег Цилюрик

Захват мьютекса

Захват мьютекса может производиться тремя разными функциями, в основе которых лежит функция из native QNX API SyncMutexLock().

Простой захват

int pthread_mutex_lock(pthread_mutex_t* mutex);

Функция захватывает мьютекс, на который ссылается mutex. Если мьютекс уже захвачен другим потоком, то вызвавший поток блокируется до освобождения мьютекса и после этого захватывает его. Только после этого функция pthread_mutex_lock() возвращает управление. Если захватить мьютекс пытается поток, который им уже владеет, то поведение функции pthread_mutex_lock() будет зависеть от значений атрибутов мьютекса, указанных при его создании. QNX предоставляет возможность рекурсивного захвата мьютекса при соответствующих настройках атрибутов (см. выше раздел «Параметры мьютекса»). При создании мьютекса с параметрами по умолчанию попытка повторного захвата мьютекса ни к чему не приводит. Если включен режим контроля ошибок и отключен рекурсивный захват мьютекса, функция pthread_mutex_lock() возвращает EDEADLK при попытке повторного захвата мьютекса тем же потоком.

Функция pthread_mutex_lock() может возвращать следующие значения: EOK — успешное завершение;

EAGAIN — недостаточно системных ресурсов для захвата мьютекса;

EDEADLK — вызывающий поток уже владеет мьютексом и мьютекс не поддерживает рекурсивный захват (режим контроля ошибок);

EINVAL — некорректное значение параметра mutex.

Попытка захвата

int pthread_mutex_trylock(pthread_mutex_t* mutex);

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

Возвращаемые значения:

EOK — успешное завершение;

EAGAIN — недостаточно системных ресурсов для захвата мьютекса;

EBUSY — мьютекс mutex уже захвачен;

EINVAL — некорректное значение параметра mutex.

Захват с установкой времени ожидания

#include <pthread.h>

#include <time.h>

int pthread_mutex_timedlock(pthread_mutex_t* mutex,

 const struct timespec* abs_timeout);

Функция проверяет, свободен ли мьютекс (mutex), и если да, то поток, в котором вызвана функция, захватывает этот мьютекс. Если мьютекс уже захвачен, вызвавший поток блокируется до освобождения мьютекса либо до наступления времени, указанного в аргументе abs_timeout. Если это время уже наступило, поток не блокируется вообще, но захват все-таки произойдет, если мьютекс свободен.

Наступление времени определяется по часам REALTIME_CLOCK, когда значение часов оказывается равным или большим значения, указанного в abs_timeout. Тип данных timespec определен в файле <time.h>.

Если мьютекс создан с атрибутом протокола PRIO_INHERIT, то после выхода потока из блокировки на мьютексе по тайм-ауту приоритет владельца мьютекса подвергается пересмотру в соответствии с приоритетами потоков, оставшихся в очереди на захват мьютекса.

Возвращаемые значения:

EOK — успешное завершение;

EAGAIN — недостаточно системных ресурсов для захвата мьютекса;

EDEADLK — вызывающий поток уже владеет мьютексом, который не поддерживает рекурсивный захват (режим контроля ошибок);

EINVAL — мьютекс использует протокол граничного приоритета для предотвращения инверсии (атрибут protocol установлен в значение PTHREAD_PRIO_PROTECT), но приоритет вызвавшего потока выше граничного приоритета, присвоенного мьютексу; поток должен быть блокирован (мьютекс не свободен), а значение поля abs_timeout, показывающее количество наносекунд, меньше нуля или больше 1000 миллионов; переменная, на которую указывает mutex, не является инициированным объектом — мьютексом.

ETIMEDOUT — мьютекс не может быть захвачен, поскольку указанный тайм-аут истек.

Освобождение мьютекса

int pthread_mutex_unlock(pthread_mutex_t* mutex);

Функция pthread_mutex_unlock() освобождает мьютекс, на который ссылается переменная mutex. Вызвавший поток должен быть владельцем мьютекса. Если есть потоки, блокированные в ожидании освобождения мьютекса, то поток с наивысшим приоритетом (или при равных приоритетах дольше всех ждавший) выходит из блокированного состояния и становится владельцем мьютекса.

Для мьютексов, разрешающих рекурсивный захват, функция освобождения должна вызываться столько же раз, сколько и функция захвата.

Возвращаемые значения:

EOK — успешное завершение;

EINVAL — переменная, на которую указывает mutex, не является инициализированным объектом — мьютексом;

EPERM — вызвавший поток не является владельцем мьютекса.

Разрушение объекта мьютекс

int pthread_mutex_destroy(pthread_mutex_t* mutex);

Вызов разрушает объект мьютекс, на который указывает переменная mutex. После чего эта переменная не может быть использована без предварительного вызова pthread_mutex_init().

Возвращаемые значения:

EOK — успешное завершение;

EBUSY - мьютекс захвачен и не может быть разрушен до освобождения;

EINVAL — переменная, на которую указывает mutex, не является инициированным объектом - мьютексом.

Операции, не поддерживаемые POSIX

В native QNX API есть ряд функций работы с мьютексом, которые не определены POSIX-стандартом, однако они могут оказаться весьма полезными. Поскольку тип POSIX-мьютекса порождается от sync_t, то вполне возможно использование комбинации функций, определенных POSIX, и «родных» native-функций QNX. Однако необходимо помнить, что в таком случае ни о какой межсистемной совместимости говорить уже не приходится.

Восстановление «мертвого» мьютекса

#include <sys/neutrino.h>

int SyncMutexRevive(sync_t* sync);

int SyncMutexRevive_r(sync_t* sync);

Эти функции[36] предназначены для восстановления мьютекса, который находится в состоянии блокирования DEAD. Мьютекс попадает в состояние DEAD, когда память, использованная при захвате мьютекса, освобождается. Такое может произойти, например, когда умирает поток, захвативший мьютекс, расположенный в разделяемой памяти. В результате вызова вызвавший поток становится владельцем мьютекса, и его счетчик захватов устанавливается в 1 для рекурсивного мьютекса.

Ошибки выполнения функции:

ЕFAULT — ошибка при обращении к указанным в аргументах переменным;

EINVAL — указанный объект синхронизации не существует или не находится в состоянии DEAD;

ETIMEDOUT — отмена вызова по тайм-ауту ядра (устанавливается вызовом TimerTimeout()).

Установка уведомления о «смерти» мьютекса

Определить состояние мьютекса как DEAD можно с помощью функции SyncMutexEvent(), которая определяет событие, связанное со «смертью» мьютекса.

#include <sys/neutrino.h>

int SyncMutexEvent(sync_t* sync, struct sigevent* event);

int SyncMutexEvent_r(sync_t* sync, struct sigevent* event);

Данная функция предназначена для установки обработчика ситуации, когда мьютекс попадает в состояние DEAD (то есть перераспределяется память, из которой произошел захват мьютекса). Захватить мьютекс, оказавшийся в состоянии DEAD, можно далее с помощью вызова функции SyncMutexRevive().

Ошибки выполнения функции:

EAGAIN — в данный момент ядро не имеет ресурсов для обработки запроса;

EFAULT — ошибка произошла при попытке обращения к sync;

EINVAL — объект синхронизации, на который указывает sync, не существует.

Пример применения мьютекса

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

/* Шаблонный класс очереди данных */

template <class T> class CDataQueue {

public:

 CDataQueue() { pthread_mutex_init(&_mutex, NULL); }

 ~CDataQueue() { pthread_mutex_destroy(&_mutex); }

 void push(T _new_data) {

  pthread_mutex_lock(&_mutex);

  data_queue.push(_new_data);

  data_event.reset();

  pthread_mutex_unlock(&_mutex);

 }

 T pop() {

  data_event.wait();


Олег Цилюрик читать все книги автора по порядку

Олег Цилюрик - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки mybooks.club.


QNX/UNIX: Анатомия параллелизма отзывы

Отзывы читателей о книге QNX/UNIX: Анатомия параллелизма, автор: Олег Цилюрик. Читайте комментарии и мнения людей о произведении.

Прокомментировать
Подтвердите что вы не робот:*
Подтвердите что вы не робот:*
Все материалы на сайте размещаются его пользователями.
Администратор сайта не несёт ответственности за действия пользователей сайта..
Вы можете направить вашу жалобу на почту librarybook.ru@gmail.com или заполнить форму обратной связи.