Новое в стандарте POSIX.1-2008
Введение
В настояшей публикации, дополняющий монографии [1] и [2], рассматриваются изменения, производенные в стандарте на мобильный интерфейс операционной системы (POSIX) в редакции от 2008 года, именуемой далее POSIX.1-2008 [3]. Эти изменения можно разделить на следующие группы:
- удаление функций и символов из стандарта;
- изменение статуса функций и символов;
- введение в стандарт новых функций и символов.
В свою очередь, при изменении статуса функций и символов он может как повыситься (функции и символы переводятся в разряд обязательных), так и понизиться (что осуществляется путем перевода функций и символов в разряд устаревших).
Функции и символы, которые были удалены
Ниже приведен список функций и символов, присутствовавших в более ранних версиях стандарта POSIX, но удаленных из POSIX.1-2008:
- bcmp() сравнение областей памяти;
- bcopy() копирование области памяти;
- bsd_signal() упрощенная работа с сигналами;
- bzero() обнуление области памяти;
- ecvt() преобразование вещественного числа в цепочку символов;
- fcvt() преобразование вещественного числа в цепочку символов;
- ftime() опрос текущих даты и времени;
- gcvt() преобразование вещественного числа в цепочку символов;
- getcontext() опрос текущего пользовательского контекста;
- gethostbyaddr() случайный доступ к сетевой базе данных о хостах узлах сети по ключам - адресам хостов;
- gethostbyname() случайный доступ к сетевой базе данных о хостах - узлах сети по ключам - именам хостов;
- getwd() опрос абсолютного маршрутного имени текущего каталога;
- h_errno код ошибки, возвращенный сетевой базой данных;
- index() поиск первого вхождения символа в цепочке символов;
- makecontext() модификация пользовательского контекста;
- mktemp() генерация уникального имени файла;
- pthread_attr_getstackaddr() опрос атрибута потоков управления - адреса стека;
- pthread_attr_setstackaddr() установка атрибута потоков управления - адреса стека;
- rindex() поиск последнего вхождения символа в цепочке символов;
- scalb() опрос показателя вещественного числа в машинной системе счисления;
- setcontext() установка текущего пользовательского контекста;
- swapcontext() перестановка пользовательских контекстов;
- ualarm() установка интервального таймера;
- usleep() приостановка выполнения на заданный промежуток времени;
- vfork() создание нового процесса с разделением виртуальной памяти;
- wcswcs() поиск подцепочки широких символов.
Функции и символы, ставшие устаревшими
Следующие функции и символы в стандарте POSIX.1-2008 переведены в разряд устаревших:
- _longjmp() нелокальный переход;
- _setjmp() установка для нелокальных переходов;
- _tolower() приведение к строчным буквам;
- _toupper() приведение к прописным буквам;
- asctime() преобразование даты и времени в цепочку символов;
- asctime_r() преобразование даты и времени в цепочку символов;
- ctime() преобразование значения времени в цепочку символов;
- ctime_r() преобразование значения времени в цепочку символов;
- ftw() рекурсивный обход иерархии каталогов;
- getitimer() опрос текущих характеристик интервального таймера;
- gets() чтение строки со стандартного ввода;
- gettimeofday() опрос текущего времени с повышенной точностью;
- isascii() проверка, принадлежит ли символ множеству 7-битных символов US-ASCII;
- pthread_getconcurrency() опрос уровня параллелизма потоков управления;
- pthread_setconcurrency() установка уровня параллелизма потоков управления;
- rand_r() генерация последовательности псевдослучайных целых чисел;
- setitimer() установка текущих характеристик интервального таймера;
- setpgrp() установка идентификатора группы процесса;
- sighold() добавление сигнала в маску сигналов вызывающего процесса;
- sigignore() установка режима игнорирования сигнала;
- sigpause() удаление сигнала из маски сигналов и приостановка вызывающего процесса;
- sigrelse() удаление сигнала из маски сигналов вызывающего процесса;
- sigset() модификация режима реагирования на сигнал;
- siginterrupt() разрешить сигналу прерывать функции;
- tempnam() генерация имени для временного файла;
- tmpnam() генерация имени для временного файла;
- toascii() преобразование в 7-битные символы US-ASCII;
- ulimit() опрос и установка ограничений процесса;
- utime() изменение ассоциированных с файлами данных о времени.
Функции и символы, ставшие обязательными
Следующие функции и символы в стандарте POSIX.1-2008 переведены в разряд обязательных:
- aio_cancel() аннулирование запросов на асинхронный ввод/вывод, ожидающих обработки;
- aio_error() опрос кода ошибки операции асинхронного ввода/вывода;
- aio_fsync() асинхронная синхронизация файла;
- aio_read() асинхронное чтение;
- aio_return() опрос кода завершения операции асинхронного ввода/вывода;
- aio_suspend() ожидание завершения операций асинхронного ввода/вывода;
- aio_write() асинхронная запись;
- asctime_r() преобразование даты и времени в цепочку символов;
- catclose() закрытие каталога сообщений;
- catgets() чтение сообщения из каталога сообщений;
- catopen() открытие каталога сообщений;
- clock_getres() опрос разрешающей способности часов;
- clock_gettime() опрос показаний часов;
- clock_nanosleep() приостановка выполнения текущего потока управления;
- clock_settime() установка показаний часов;
- ctime_r() преобразование значения времени в цепочку символов;
- dlclose() закрытие выполнимого объектного файла;
- dlerror() получение диагностической информации о процессе динамического редактирования внешних связей;
- dlopen() открытие выполнимого объектного файла;
- dlsym() получение адреса символа из открытого выполнимого объектного файла;
- fchdir() смена текущего каталога;
- flockfile() блокирование потоком управления объекта, обрабатываемого средствами stdio;
- fstatvfs() получение интегральной информации о файловой системе, содержащей заданный файл;
- ftrylockfile() попытка блокирования потоком управления объекта, обрабатываемого средствами stdio;
- funlockfile() снятие блокировки потоком управления с объекта, обрабатываемого средствами stdio;
- getc_unlocked() вариант getc() без требований потоковой безопасности;
- getchar_unlocked() вариант getchar() без требований потоковой безопасности;
- getgrgid_r() поиск элемента базы данных групп по идентификатору группы;
- getgrnam_r() поиск элемента базы данных групп по имени;
- getlogin_r() опрос входного имени;
- getpgid() опрос идентификатора группы процесса;
- getpwnam_r() поиск элемента базы данных пользователей по имени;
- getpwuid_r() поиск элемента базы данных пользователей по идентификатору пользователя;
- getsid() опрос идентификатора группы процесса - лидера сеанса;
- getsubopt() грамматический разбор аргументов - опций второго уровня из цепочки символов;
- gmtime_r() преобразование значения времени в разбитое на компоненты всемирное время;
- iconv() преобразование последовательности символов из одной кодировки в другую;
- iconv_close() закрытие дескриптора преобразования из одной кодировки в другую;
- iconv_open() получение дескриптора (открытие) преобразования из одной кодировки в другую;
- lchown() смена владельца и группы символьной ссылки;
- lio_listio() ввод/вывод, управляемый списком;
- localtime_r() преобразование значения времени в разбитое на компоненты местное время;
- mkstemp() генерация уникального имени файла;
- mmap() построение отображения объекта в памяти на группу страниц из адресного пространства вызывающего процесса;
- mprotect() динамическая смена разрешенных видов доступа к отображенным страницам;
- munmap() отмена отображений в адресное пространство процессов;
- nanosleep() приостановка выполнения текущего потока управления;
- nl_langinfo() получение детальной информации о языково-культурной среде;
- poll() мультиплексирование ввода/вывода в пределах набора файловых дескрипторов;
- posix_trace_timedgetnext_event() чтение очередного события из потока трассировки;
- pread() чтение из файла без изменения указателя текущей позиции;
- pthread_atfork() регистрация обработчиков, ассоциированных с функцией fork();
- pthread_attr_destroy() разрушение атрибутных объектов, используемых при создании потоков управления;
- pthread_attr_getdetachstate() опрос атрибута обособленности в атрибутных объектах потоков управления;
- pthread_attr_getguardsize() опрос атрибута - размера защитной области, служащей цели обнаружения переполнения стека, в атрибутных объектах потоков управления;
- pthread_attr_getschedparam() опрос атрибутов планирования в атрибутных объектах потоков управления;
- pthread_attr_init() инициализация атрибутных объектов, используемых при создании потоков управления;
- pthread_attr_setdetachstate() установка атрибута обособленности в атрибутных объектах потоков управления;
- pthread_attr_setguardsize() установка атрибута - размера защитной области, служащей цели обнаружения переполнения стека, в атрибутных объектах потоков управления;
- pthread_attr_setschedparam() установка атрибутов планирования в атрибутных объектах потоков управления;
- pthread_barrier_destroy() разрушение барьеров;
- pthread_barrier_init() инициализация барьеров;
- pthread_barrier_wait() синхронизация на барьере;
- pthread_barrierattr_destroy() разрушение атрибутных объектов барьеров;
- pthread_barrierattr_init() инициализация атрибутных объектов барьеров;
- pthread_cancel() заказ терминирования извне потока управления с заданным идентификатором;
- pthread_cleanup_pop() извлечение верхнего элемента из стека функций-обработчиков завершения вызывающего потока управления и его (обработчика) выполнение;
- pthread_cleanup_push() помещение элемента в стек функций-обработчиков завершения вызывающего потока управления;
- pthread_cond_broadcast() разблокирование (прекращение ожидания) потоков управления, блокированных на переменной условия;
- pthread_cond_destroy() разрушение переменных условия;
- pthread_cond_init() инициализация переменных условия;
- pthread_cond_signal() разблокирование (прекращение ожидания) потока управления, блокированного на переменной условия;
- pthread_cond_timedwait() блокирование (ожидание) на переменной условия с контролем времени ожидания;
- pthread_cond_wait() блокирование на переменной условия;
- pthread_condattr_destroy() разрушение атрибутных объектов переменных условия;
- pthread_condattr_getclock() опрос атрибута - идентификатора часов реального времени, используемых для ограничения ожидания на переменной условия, в атрибутных объектах переменных условия;
- pthread_condattr_init() инициализация атрибутных объектов переменных условия;
- pthread_condattr_setclock() установка атрибута - идентификатора часов реального времени, используемых для ограничения ожидания на переменной условия, в атрибутных объектах переменных условия;
- pthread_create() создание потока управления;
- pthread_detach() динамическое обособление потока управления;
- pthread_equal() сравнение на равенство структур типа pthread_t ;
- pthread_exit() терминирование вызывающего потока управления;
- pthread_getspecific() извлечение индивидуальных данных потока управления;
- pthread_join() ожидание завершения заданного потока управления;
- pthread_key_create() создание ключа индивидуальных данных потоков управления;
- pthread_key_delete() удаление ключа индивидуальных данных потоков управления;
- pthread_mutex_destroy() разрушение мьютексов;
- pthread_mutex_init() инициализация мьютексов;
- pthread_mutex_lock() захват мьютексов;
- pthread_mutex_timedlock() попытка захвата мьютексов с контролем времени ожидания;
- pthread_mutex_trylock() попытка захвата мьютексов без блокирования вызывающего потока управления;
- pthread_mutex_unlock() освобождение мьютексов;
- pthread_mutexattr_destroy() разрушение атрибутных объектов мьютексов;
- pthread_mutexattr_gettype() опрос атрибутов мьютекса в атрибутных объектах;
- pthread_mutexattr_init() инициализация атрибутных объектов мьютексов;
- pthread_mutexattr_settype() установка атрибутов мьютекса в атрибутных объектах;
- pthread_once() функция для решения проблемы однократного выполнения инициализирующих действий в многопотоковой среде;
- pthread_rwlock_destroy() разрушение блокировок;
- pthread_rwlock_init() инициализация блокировок;
- pthread_rwlock_rdlock() установка блокировки на чтение;
- pthread_rwlock_timedrdlock() попытка установки блокировки на чтение с контролем времени ожидания;
- pthread_rwlock_timedwrlock() попытка установки блокировки на запись с контролем времени ожидания;
- pthread_rwlock_tryrdlock() попытка установки блокировки на чтение без блокирования вызывающего потока управления;
- pthread_rwlock_trywrlock() попытка установки блокировки на запись без блокирования вызывающего потока управления;
- pthread_rwlock_unlock() снятие блокировки чтение-запись;
- pthread_rwlock_wrlock() установка блокировки на запись;
- pthread_rwlockattr_destroy() разрушение атрибутных объектов блокировок;
- pthread_rwlockattr_init() инициализация атрибутных объектов блокировок;
- pthread_self() опрос идентификатора вызвавшего потока;
- pthread_setcancelstate() установка состояния восприимчивости к терминированию потока управления;
- pthread_setcanceltype() установка типа терминирования потока управления;
- pthread_setspecific() ассоциирование индивидуальных данных потока управления;
- pthread_spin_destroy() разрушение спин-блокировок;
- pthread_spin_init() инициализация спин-блокировок;
- pthread_spin_lock() установка спин-блокировки;
- pthread_spin_trylock() попытка установки спин-блокировки без блокирования вызывающего потока управления;
- pthread_spin_unlock() снятие спин-блокировки;
- pthread_testcancel() создание в вызывающем потоке управления точки терминирования;
- putc_unlocked() вариант putc() без требований потоковой безопасности;
- putchar_unlocked() вариант putchar() без требований потоковой безопасности;
- pwrite() запись в файл без изменения указателя текущей позиции;
- rand_r() генерация последовательности псевдослучайных целых чисел;
- readdir_r() чтение каталога;
- sem_close() закрытие именованного семафора;
- sem_destroy() ликвидация неименованных семафоров;
- sem_getvalue() опрос значения семафора;
- sem_init() создание неименованных семафоров;
- sem_open() создание именованного семафора;
- sem_post() освобождение семафора;
- sem_timedwait() попытка захвата семафора с контролем времени ожидания;
- sem_trywait() попытка захвата семафора без блокирования вызывающего потока управления;
- sem_unlink() удаление именованного семафора;
- sem_wait() захват семафора;
- sigqueue() генерирация сигнала реального времени;
- sigtimedwait() ожидание доставки сигнала реального времени с контролем времени ожидания;
- sigwaitinfo() ожидание доставки сигнала реального времени;
- statvfs() получение интегральной информации о файловых системах, содержащих заданные файлы;
- strcasecmp() сравнение цепочек символов без учета регистра;
- strdup() дублирование цепочки символов;
- strerror_r() получение цепочки символов - сообщения об ошибке;
- strfmon() преобразование денежного значения в цепочку символов;
- strncasecmp() сравнение цепочек символов без учета регистра с ограничением числа символов;
- strtok_r() разбиение строки символов на лексемы;
- tcgetsid() опрос идентификатора группы процессов лидера сеанса по файловому дескриптору управляющего терминала;
- timer_create() создание для процесса таймера, генерирующего уведомления о наступлении заданного момента в виде сигнала реального времени;
- timer_delete() удаление таймера;
- timer_getoverrun() опрос числа избыточных срабатываний таймера;
- timer_gettime() запоминание в структуре текущих характеристик таймера с заданным идентификатором;
- timer_settime() взведение или снятие таймера со взвода с установлением новых характеристик;
- truncate() установка размера файла равным заданной величине;
- ttyname_r() получение маршрутного имени терминала;
- waitid() ожидание изменения состояния порожденного процесса.
Можно видеть, что основная часть функций, ставших обязательными, обслуживает потребности приложений реального времени. Таким образом, поддержка реального времени - обязательный атрибут современных операционных систем.
Новые функции и символы
В стандарте POSIX.1-2008 появились следующие новые функции и символы:
- alphasort() сравнение алфавитного порядка двух элементов каталога;
- dirfd() выделение файлового дескриптора потока-каталога;
- dprintf() аналог fprintf() с записью результатов не в поток, а по файловому дескриптору;
- duplocale() дублирование объекта, описывающего языково-культурную среду;
- faccessat() опрос доступности файла относительно файлового дескриптора каталога;
- fchmodat() смена режима доступа к файлу относительно файлового дескриптора каталога;
- fchownat() смена владельца и группы файла относительно файлового дескриптора каталога;
- fdopendir() открытие каталога, ассоциированного с файловым дескриптором;
- fexecve() выполнение файла; аналог execve(), только файл задается не маршрутным именем, а файловым дескриптором;
- fmemopen() открытие потока с заданным буфером в памяти;
- freelocale() освобождение ресурсов, выделенных для объекта, описывающего языково-культурную среду;
- fstatat() опрос статуса файла с возможностью явного задания начальной точки для интерпретации относительных маршрутных имен;
- futimens() установка времени модификации и доступа к файлу, заданному файловым дескриптором;
- getdelim() чтение из потока до заданного разделителя;
- getline() чтение из потока до символа новой строки;
- isalnum_l() проверка, является ли заданный символ буквенно-цифровым в заданной языково-культурной среде;
- isalpha_l() проверка, является ли заданный символ буквой в заданной языково-культурной среде;
- isblank_l() проверка, является ли заданный символ пробелом в заданной языково-культурной среде;
- iscntrl_l() проверка, является ли заданный символ управляющим в заданной языково-культурной среде;
- isdigit_l() проверка, является ли заданный символ цифрой в заданной языково-культурной среде;
- isgraph_l() проверка, является ли заданный символ видимым в заданной языково-культурной среде;
- islower_l() проверка, является ли заданный символ строчной буквой в заданной языково-культурной среде;
- isprint_l() проверка, является ли заданный символ печатным в заданной языково-культурной среде;
- ispunct_l() проверка, является ли заданный символ знаком пунктуации в заданной языково-культурной среде;
- isspace_l() проверка, является ли заданный символ пробельным в заданной языково-культурной среде;
- isupper_l() проверка, является ли заданный символ прописной буквой в заданной языково-культурной среде;
- iswalnum_l() проверка, является ли заданный широкий символ буквенно-цифровым в заданной языково-культурной среде;
- iswalpha_l() проверка, является ли заданный широкий символ буквой в заданной языково-культурной среде;
- iswblank_l() проверка, является ли заданный широкий символ пробелом в заданной языково-культурной среде;
- iswcntrl_l() проверка, является ли заданный широкий символ управляющим в заданной языково-культурной среде;
- iswctype_l() проверка, принадлежит ли заданный широкий символ заданному классу в заданной языково-культурной среде;
- iswdigit_l() - проверка, является ли заданный широкий символ цифрой в заданной языково-культурной среде;
- iswgraph_l() проверка, является ли заданный широкий символ видимым в заданной языково-культурной среде;
- iswlower_l() проверка, является ли заданный широкий символ строчной буквой в заданной языково-культурной среде;
- iswprint_l() проверка, является ли заданный широкий символ печатным в заданной языково-культурной среде;
- iswpunct_l() проверка, является ли заданный широкий символ знаком пунктуации в заданной языково-культурной среде;
- iswspace_l() проверка, является ли заданный широкий символ пробельным в заданной языково-культурной среде;
- iswupper_l() проверка, является ли заданный широкий символ прописной буквой в заданной языково-культурной среде;
- iswxdigit_l() проверка, является ли заданный широкий символ шестнадцатеричной цифрой в заданной языково-культурной среде;
- isxdigit_l() проверка, является ли заданный символ шестнадцатеричной цифрой в заданной языково-культурной среде;
- linkat() создание ссылки на файл с возможностью явного задания двух каталогов для интерпретации относительных маршрутных имен;
- mbsnrtowcs() преобразование цепочки символов с цепочку широких символов с ограничением числа символов;
- mkdirat() создание каталога с возможностью явного задания начальной точки для интерпретации относительных маршрутных имен;
- mkdtemp() создание уникального каталога или обычного файла;
- mkfifoat() создание канала с возможностью явного задания начальной точки для интерпретации относительных маршрутных имен;
- mknodat() создание каталога, специального или обычного файла с возможностью явного задания начальной точки для интерпретации относительных маршрутных имен;
- newlocale() создание или модийикацоя объекта, описывающего языково-культурную среду;
- openat() открытие файла с возможностью явного задания начальной точки для интерпретации относительных маршрутных имен;
- open_memstream() открытие потока ввода/вывода, ассоциированного с динамически выделенным буфером в памяти, размер которого задается в байтах;
- open_wmemstream() открытие потока ввода/вывода, ассоциированного с динамически выделенным буфером в памяти, размер которого задается в широких символах;
- psiginfo() вывод в стандартный протокол информации о сигнале, заданном структурой;
- psignal() вывод в стандартный протокол информации о сигнале, заданном номером;
- pthread_mutexattr_getrobust() опрос значения атрибута устойчивости мьютексов;
- pthread_mutexattr_setrobust() установка значения атрибута устойчивости мьютексов;
- pthread_mutex_consistent() отметка состояния, защищенного устойчивым мьютексом, как непротиворечивого;
- readlinkat() чтение содержимое символьной ссылки с возможностью явного задания начальной точки для интерпретации относительных маршрутных имен;
- renameat() переименование файла с возможностью явного задания начальной точки для интерпретации относительных маршрутных имен;
- scandir() просмотр каталогов с обработкой элементов;
- stpcpy() копирование цепочки символов с возратом указателя на конец результата;
- stpncpy() копирование цепочки символов с ограничением числа символов и с возратом указателя на конец результата;
- strcasecmp_l() сравнение цепочек символов без учета регистра в явно заданной языково-культурной среде;
- strcoll_l() сравнение цепочек символов с использованием категории LC_COLLATE в явно заданной языково-культурной среде;
- strfmon_l() преобразование денежного значения в цепочку символов в явно заданной языково-культурной среде;
- strncasecmp_l() сравнение цепочек символов без учета регистра с ограничением числа символов в явно заданной языково-культурной среде;
- strndup() дублирование цепочки символов с ограничением числа символов;
- strnlen() опрос длины цепочки символов с ограничением числа символов;
- strsignal() опрос имени сигнала;
- strxfrm_l() преобразование цепочки символов в явно заданной языково-культурной среде;
- symlinkat() создание символьной ссылки с возможностью явного задания начальной точки для интерпретации относительных маршрутных имен;
- tolower_l() преобразование прописных букв в строчные в явно заданной языково-культурной среде;
- toupper_l() преобразование строчных букв в прописные в явно заданной языково-культурной среде;
- towctrans_l() транслитерация широких символов в явно заданной языково-культурной среде;
- towlower_l() преобразование широких символов - прописных букв в строчные в явно заданной языково-культурной среде;
- towupper_l() преобразование широких символов - строчных букв в прописные в явно заданной языково-культурной среде;
- unlinkat() удаление элемента каталога с возможностью явного задания начальной точки для интерпретации относительных маршрутных имен;
- uselocale() использование заданной языково-культурной среды в текущем потоке управления;
- utimensat() установка времени модификации и доступа к файлу с возможностью явного задания начальной точки для интерпретации относительных маршрутных имен;
- vdprintf() форматный вывод списка аргументов stdarg ;
- wcpcpy() копирование цепочки широких символов с возратом указателя на конец результата;
- wcpncpy() копирование цепочки широких символов с ограничением числа символов и с возратом указателя на конец результата;
- wcscasecmp() сравнение цепочек широких символов без учета регистра;
- wcscasecmp_l() сравнение цепочек широких символов без учета регистра в явно заданной языково-культурной среде;
- wcscoll_l() сравнение цепочек широких символов с использованием категории LC_COLLATE в явно заданной языково-культурной среде;
- wcsdup() дублирование цепочки широких символов;
- wcsncasecmp() сравнение цепочек широких символов без учета регистра с ограничением числа символов;
- wcsncasecmp_l() сравнение цепочек широких символов без учета регистра с ограничением числа символов в явно заданной языково-культурной среде;
- wcsnlen() опрос длины цепочки широких символов с ограничением числа символов;
- wcsnrtombs() преобразование цепочки широких символов в цепочку символов с ограничением числа широких символов;
- wcsxfrm_l() преобразование цепочки широких символов в явно заданной языково-культурной среде;
- wctrans_l() определение отображения символов в явно заданной языково-культурной среде;
- wctype_l() определение класса символов в явно заданной языково-культурной среде.
Устойчивость мьютексов
Из предыдущих разделов видно, что никаких принципиальных изменений в версии стандарта POSIX.1-2008 не произошло. Модификации в подавляющем большинстве носят очевидный, технический характер.
С концептуальной точки зрения единственным существенным нововведением в стандарте POSIX.1-2008 является атрибут устойчивости мьютексов, который определяет поведение совокупности процессов и/или потоков управления после терминирования владельца мьютекса в тот промежуток времени, когда этот мьютекс им захвачен. Подобная ситуация заслуживает особого внимания, так как она чревата возникновением тупиков, если другие процессы и/или потоки управления не могут освободить мьютекс.
В стандарте POSIX.1-2008 определены следующие значения атрибута устойчивости мьютексов:
PTHREAD_MUTEX_STALLED
Это подразумеваемое значение. Никаких специальных действий в случае терминирования владельца мьютекса не предпринимается.
PTHREAD_MUTEX_ROBUST
Если процесс, содержащий поток управления, являющийся владельцем устойчивого мьютекса, терминируется в тот промежуток времени, когда этот мьютекс им захвачен, следующий поток управления, который захватывает мьютекс, должен быть уведомлен о терминировании путем возврата функцией захвата значения EOWNERDEAD. В ситуации, когда терминируется поток управления - владелец мьютекса, аналогичное уведомление не обязательно, но может быть предоставлено.
Уведомленный поток управления может затем вновь попытаться отметить состояние, защищенное устойчивым мьютексом, как непротиворечивое, вызвав функцию pthread_mutex_consistent(). Последующий успешный вызов функции pthread_mutex_unlock() приведет к освобождению мьютекса, а другие потоки управления получат возможность использовать этот мьютекс обычным образом. Если мьютекс освобождается без вызова функции pthread_mutex_consistent(), он должен оставаться в перманентно некорректном состоянии, а все попытки его захвата должны завершаться неудачей с кодом ошибки ENOTRECOVERABLE. Единственной допустимой операцией над подобный мьютексом является pthread_mutex_destroy().
Функции pthread_mutexattr_getrobust() и pthread_mutexattr_setrobust(), служащие, соответственно, для опроса и установки значения атрибута устойчивости мьютексов, описываются следующим образом (см. листинг P.1):
#include <pthread.h> int pthread_mutexattr_getrobust (const pthread_mutexattr_t *restrict attr, int *restrict robust); int pthread_mutexattr_setrobust (pthread_mutexattr_t *attr, int robust);Листинг P.1. Описание функций опроса и установки значения атрибута устойчивости мьютексов
В случае успешного завершения результ функции равен нулю, а текущее значение атрибут устойчивости помещается по указателю robust.
Отметим, что содержательные действия, требующиеся для возврата мьютекса в непротиворечивое состояние, целиком и полностью зависят от приложения. Если подобный возврат невозможен, устойчивые мьютексы могут использоваться для уведомления о возникновении рассогласования путем обращения к функции pthread_mutex_unlock() без предварительного вызова pthread_mutex_consistent(). После этого остается только разрушить мьютекс, обратившись к функции pthread_mutex_destroy(), и затем повторно инициализировать его посредством вызова функции pthread_mutex_init(). Правда, для этого требуется наличие координации с потоками управления, блокированными на мьютексе, поскольку в противном случае вызов функции захвата мьютекса pthread_mutex_lock() со ссылкой на объект-мьютекс, ставший недействительным после обращения к функции pthread_mutex_destroy(), приведет к неопределенному поведению.
Упоминавшаяся выше функция pthread_mutex_consistent() описывается очевидным образом (см. листинг P.2):
#include <pthread.h> int pthread_mutex_consistent (pthread_mutex_t *mutex);Листинг P.2. Описание функции отметки состояния, защищенного устойчивым мьютексом, как непротиворечивого
Заключение
Изменения, произведенные в стандарте POSIX.1-2008, можно назвать косметическими, за исключением перевода средств реального времени в разряд обязательных. Вероятно, следующая версия стандарта привнесет больше нового.
Литература
- Галатенко В.А. Программирование в стандарте POSIX. Под ред. академика РАН В.Б. Бетелина. - М.: ИНТУИТ.РУ, 2004, 560 с.
- Галатенко В.А. Программирование в стандарте POSIX. Часть 2. Под ред. академика РАН В.Б. Бетелина. - М.: ИНТУИТ.РУ, 2004, 424 с.
- The Open Group Base Specifications Issue 7. IEEE Std 1003.1-2008.