Чтение онлайн

на главную - закладки

Жанры

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

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 для рекурсивного мьютекса.

36

Функции

SyncMutexRevive
и
SyncMutexRevive_r
, из которых вторая является потокобезопасной формой первой, как это описывалось выше, отличаются между собой только способом уведомления об ошибке: первая форма возвращает -1 в случае ошибки и устанавливает
errno
, а вторая непосредственно возвращает код ошибки.

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

Е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;

pthread_mutex_lock(&_mutex);

T res = data_queue.front;

data_queue.pop;

pthread_mutex_unlock(&_mutex);

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

Возвышение Меркурия

Кронос Александр
1. Меркурий
Фантастика:
героическая фантастика
попаданцы
аниме
5.00
рейтинг книги
Возвышение Меркурия

Смертник из рода Валевских. Книга 1

Маханенко Василий Михайлович
1. Смертник из рода Валевских
Фантастика:
фэнтези
рпг
аниме
5.40
рейтинг книги
Смертник из рода Валевских. Книга 1

Начальник милиции

Дамиров Рафаэль
1. Начальник милиции
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Начальник милиции

Счастливый торт Шарлотты

Гринерс Эва
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Счастливый торт Шарлотты

Я снова не князь! Книга XVII

Дрейк Сириус
17. Дорогой барон!
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Я снова не князь! Книга XVII

Вечный Данж VI

Матисов Павел
6. Вечный Данж
Фантастика:
фэнтези
7.40
рейтинг книги
Вечный Данж VI

Последний попаданец 3

Зубов Константин
3. Последний попаданец
Фантастика:
фэнтези
юмористическое фэнтези
рпг
5.00
рейтинг книги
Последний попаданец 3

Не грози Дубровскому!

Панарин Антон
1. РОС: Не грози Дубровскому!
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Не грози Дубровскому!

Возвышение Меркурия. Книга 12

Кронос Александр
12. Меркурий
Фантастика:
героическая фантастика
попаданцы
аниме
5.00
рейтинг книги
Возвышение Меркурия. Книга 12

Найди меня Шерхан

Тоцка Тала
3. Ямпольские-Демидовы
Любовные романы:
современные любовные романы
короткие любовные романы
7.70
рейтинг книги
Найди меня Шерхан

Ваше Сиятельство 2

Моури Эрли
2. Ваше Сиятельство
Фантастика:
фэнтези
альтернативная история
аниме
5.00
рейтинг книги
Ваше Сиятельство 2

Адепт: Обучение. Каникулы [СИ]

Бубела Олег Николаевич
6. Совсем не герой
Фантастика:
фэнтези
попаданцы
9.15
рейтинг книги
Адепт: Обучение. Каникулы [СИ]

Комбинация

Ланцов Михаил Алексеевич
2. Сын Петра
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Комбинация

Мой любимый (не) медведь

Юнина Наталья
Любовные романы:
современные любовные романы
7.90
рейтинг книги
Мой любимый (не) медведь