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

на главную

Жанры

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

PTHREAD_PRIO_PROTECT
— любой поток, захвативший мьютекс и созданный с таким параметром, будет устанавливать фиксированный уровень приоритета в соответствии со значением поля
prioceiling
, возвращаемого функцией
pthread_mutexattr_getprioceiling
. Таким образом, установка этого значения в качестве протокола мьютекса приводит к реализации протокола граничного приоритета для защиты от инверсии приоритетов.

Внешний доступ

int pthread_mutexattr_setpshared(

pthread_mutexattr_t* attr, int pshared);

int pthread_mutexattr_getpshared(

const pthread_mutexattr_t* attr, int* pshared);

Эти

функции устанавливают/считывают внутреннее поле атрибутной записи мьютекса, определяющее, возможен ли доступ к мьютексу из потоков, запущенных вне процесса, в котором был создан и инициализирован мьютекс. Параметр
pshared
может принимать следующие значения:

PTHREAD_PROCESS_SHARED
— любой поток из любого процесса в системе, который может получить доступ к синхронизирующему объекту (для этого придется использовать какой-либо из методов IPC, возможно shared memory), может использовать его по назначению.

PTHREAD_PROCESS_PRIVATE
(значение по умолчанию) — мьютекс может использоваться только потоками, порожденными в том же процессе, где был инициализирован мьютекс. В документации сказано: попытка захвата мьютекса с таким значением параметра доступа к потокам из «чужого» процесса приведет к неопределенному результату. На практике же функция захвата возвращает управление в любом случае, независимо от того, был ли уже захвачен мьютекс другим потоком или нет (как будто происходит нормальный захват). Состояние мьютекса при этом никак не меняется.

Разрешение рекурсивного захвата

int pthread_mutexattr_setrecursive(

pthread_mutexattr_t* attr, int recursive);

int pthread_mutexattr_getrecursive(

const pthread_mutexattr_t* attr, int* recursive);

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

PTHREAD_RECURSIVE_ENABLE
— разрешает рекурсивный захват мьютекса;

PTHREAD_RECURSIVE_DISABLE
(значение по умолчанию) — запрещает рекурсивный захват мьютекса. В результате при попытке захвата мьютекса потоком, который им уже владеет, вызов
pthread_mutex_lock
не приведет к захвату мьютекса и вернет значение
EDEADLK
.

Определение типа мьютекса

int pthread_mutexattr_settype(

pthread_mutexattr_t* attr, int type);

int pthread_mutexattr_gettype(

const pthread_mutexattr_t* attr, int* type);

В версиях QNX 6.2.1 и 6.3 предусматривается создание мьютексов следующих типов:

PTHREAD_MUTEX_NORMAL
— для этого типа не проводится контроль «мертвой блокировки» (deadlock) в ситуации, когда поток, захвативший мьютекс, пытается захватить его повторно. Поэтому при попытке повторного захвата такого мьютекса тем же потоком этот поток будет безусловно блокирован (то есть он попадает в «мертвую блокировку», а это во всех случаях аварийная ситуация в выполнении приложения); такой мьютекс уже некому разблокировать (мьютекс может разблокироваться только своим владельцем). Попытка освободить (unlock) мьютекс такого типа, захваченный другим потоком, или освободить незахваченный мьютекс ни к чему не приводит, при этом не возвращается ошибка выполнения.

PTHREAD_MUTEX_ERRORCHECK
— включается контроль ошибок. В этом режиме регистрируются следующие ситуации:

• попытка повторного захвата мьютекса тем же потоком;

• попытка освобождения мьютекса, захваченного другим потоком;

• освобождение свободного мьютекса.

PTHREAD_MUTEX_RECURSIVE
— мьютекс, допускающий рекурсивный захват. Поток, пытающийся захватить мьютекс, уже захваченный в этом потоке, сможет это сделать, при этом количество захватов будет учитываться при освобождении мьютекса. Другой поток сможет захватить такой мьютекс только тогда, когда он будет освобожден столько же раз, сколько был захвачен. Если поток пытается освободить мьютекс, захваченный другим потоком, или свободный мьютекс, то будет возвращено сообщение об ошибке (регистрируются ошибки, предусмотренные предыдущим типом, за исключением повторного захвата, который является для рекурсивного мьютекса штатным действием).

Примечание

Обратите внимание, что разрешение рекурсивного захвата мьютекса необходимо проводить установкой двух параметров (

type
и
recursive
).

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

Освобождение параметров

int pthread_mutexattr_destroy(pthread_mutexattr_t* attr);

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

pthread_mutexattr_init
.

На этом обсуждение атрибутов заканчивается, и мы переходим непосредственно к функциям работы с мьютексом.

Операции над мьютексом

Инициализация мьютекса

int pthread_mutex_init(pthread_mutex_t* mutex,

const pthread_mutexattr_t* attr);

Структура данных

pthread_mutex_t
определена в файле
<pthread.h>
(производный тип от типа
sync_t
, который в свою очередь определен в файле
<target_nto.h>
) и имеет следующий вид:

struct _sync_t {

/* Счетчик для рекурсивного мьютекса или семафора */

int count;

/* TID потока - имеет смысл и применяется только для мьютексов */

unsigned owner;

};

Функция

pthread_mutex_init
инициализирует переданный объект мьютекс в соответствии со значением переданных атрибутов. Если вместо
attr
передать
NULL
, то мьютекс будет создан в соответствии со значениями атрибутов по умолчанию. В native QNX API эта функция реализуется вызовом
SyncTypeCreate
.
SyncTypeCreate
— единая функция для создания всех базовых объектов синхронизации QNX Neutrino.

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

Назад в СССР: 1985 Книга 4

Гаусс Максим
4. Спасти ЧАЭС
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Назад в СССР: 1985 Книга 4

Эффект Фостера

Аллен Селина
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Эффект Фостера

Санек

Седой Василий
1. Санек
Фантастика:
попаданцы
альтернативная история
4.00
рейтинг книги
Санек

Неудержимый. Книга XVI

Боярский Андрей
16. Неудержимый
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Неудержимый. Книга XVI

Кодекс Охотника. Книга XXIV

Винокуров Юрий
24. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Охотника. Книга XXIV

Царь поневоле. Том 1

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

Совок 9

Агарев Вадим
9. Совок
Фантастика:
попаданцы
альтернативная история
7.50
рейтинг книги
Совок 9

Вечная Война. Книга II

Винокуров Юрий
2. Вечная война.
Фантастика:
юмористическая фантастика
космическая фантастика
8.37
рейтинг книги
Вечная Война. Книга II

Те, кого ты предал

Берри Лу
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Те, кого ты предал

Кодекс Охотника. Книга XXII

Винокуров Юрий
22. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Кодекс Охотника. Книга XXII

Путь Шедара

Кораблев Родион
4. Другая сторона
Фантастика:
боевая фантастика
6.83
рейтинг книги
Путь Шедара

Вы не прошли собеседование

Олешкевич Надежда
1. Укротить миллионера
Любовные романы:
короткие любовные романы
5.00
рейтинг книги
Вы не прошли собеседование

Законы Рода. Том 4

Flow Ascold
4. Граф Берестьев
Фантастика:
юмористическое фэнтези
аниме
5.00
рейтинг книги
Законы Рода. Том 4

Дурная жена неверного дракона

Ганова Алиса
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Дурная жена неверного дракона