Настоящий курс является продолжением курса [1]. В принципе, разделение единой темы "Программирование в стандарте POSIX" на две части носит скорее технический, чем принципиальный характер, однако у
второй части есть свой стержень –
Основной структурной единицей приложения реального времени
является
Для задания характеристик потоков управления (и других рассматриваемых в настоящем курсе сущностей) в стандарте POSIX-2001 активно
используются
По отношению к потокам управления вводится понятие безопасных функций, которые можно вызывать параллельно в нескольких потоках без нарушения корректности их функционирования. К числу безопасных принадлежат "чистые" функции, а также функции, обеспечивающие взаимное исключение перед доступом к разделяемым объектам. Если в стандарте явно не оговорено противное, функция считается потоково-безопасной.
Для приложений реального времени исключительно важно и активно используется понятие планирования.
Под
Операции с потоками управления можно подразделить на две группы:
В таком порядке они и рассматриваются в настоящем курсе.
При анализе средств
Чтобы быть практически полезными, средства синхронизации, специально ориентированные на потоки управления, должны быть оптимизированы с учетом обеих отмеченных особенностей.
К числу таких средств, присутствующих в стандарте POSIX-2001,
принадлежат
Средства синхронизации могут использоваться для достижения двух существенно разных целей:
Тема "
Одношаговое порождение posix_spawn() и posix_spawnp().
Под сигналами реального времени понимается не нарушающее совместимости расширение общего механизма сигналов, повышающее детерминированность за счет постановки сигналов, асинхронно доставленных приложению, в очередь.
Основные понятия, ассоциированные с часами и
В качестве
Чтобы время доступа к объекту было по возможности минимальным
и не превышало заданной величины, этот объект делают резидентным в
физической памяти. Применительно к
Достижению той же цели – минимизации времени (а также унификации) доступа – служит механизм объектов в памяти.
Приоритетное
Средства асинхронного ввода/вывода позволяют прикладным
Приложения реального времени сложно не только разрабатывать, но и отлаживать, поскольку в понятие семантической корректности входит дополнительный компонент – соблюдение временных ограничений. Для решения этой проблемы в стандарте POSIX-2001 предусмотрен механизм трассировки.
Применительно к приложениям реального времени
В настоящем курсе рассматриваются также так называемые технологические интерфейсы, играющие техническую, подчиненную роль,
но необходимые для использования возможностей более высокого
уровня. К числу технологических интерфейсов отнесены функции и
утилиты для работы с системным журналом, функции для работы с
Таковы основные понятия и объекты, ставшие предметом рассмотрения в настоящем курсе.
В рамках любого pthread_self().
Порождению потоков управления обычно предшествует создание
pthread_attr_init().
Когда объект перестает быть нужным, его ликвидируют, вызывая pthread_attr_destroy().
В число поддерживаемых входят атрибуты стека (функции pthread_attr_getstack(), pthread_attr_setstack(),
pthread_attr_getguardsize(), pthread_attr_setguardsize()),
планирования (pthread_attr_getschedparam(),
pthread_attr_setschedparam(), pthread_attr_getschedpolicy(),
pthread_attr_setschedpolicy(), pthread_attr_getscope(),
pthread_attr_setscope(), pthread_attr_getinheritsched(),
pthread_attr_setinheritsched() ) и обособленности
( pthread_attr_getdetachstate(), pthread_attr_setdetachstate() ).
Обратим внимание на средство
Значения атрибутов планирования могут задаваться не только при
создании потока управления. Стандарт POSIX-2001 предоставляет средства для их динамического изменения и опроса – функции pthread_getschedparam(), pthread_setschedparam(),
pthread_setschedprio(), pthread_getconcurrency(),
pthread_setconcurrency().
К числу pthread_getcpuclockid().
Еще один атрибут потока управления – pthread_sigmask().
Все потоки управления одного pthread_key_create() создать ключ и ассоциировать с ним индивидуальные данные, воспользовавшись функцией pthread_setspecific().
В дальнейшем эти данные можно извлекать посредством функции pthread_getspecific(). Подчеркнем, что при обращении по одному
(разделяемому) ключу разные потоки будут получать доступ к разным
данным.
Создать один ключ, очевидно, нужно один раз. Для решения проблемы однократного выполнения pthread_once().
За удаление ключа pthread_key_delete().
Модель порождения потоков управления отличается от соответствующей модели для создающий поток должен обратиться лишь к одной функции – pthread_create().
От "родительского" вновь созданный
К числу средств создания потоков можно отнести и функцию . С ней можно ассоциировать обработчики, зарегистрировав их с
помощью функции pthread_atfork(). В каждом обращении к pthread_atfork() фигурируют три обработчика. Первый выполняется в
контексте потока, вызвавшего , до разветвления
pthread_exit().
Заказать pthread_cancel().
На выполнение "заказа" влияют состояние восприимчивости к
терминированию (разрешено/запрещено) и pthread_setcancelstate(), pthread_setcanceltype() и pthread_testcancel().
Стандартом POSIX-2001 предусмотрено существование pthread_cleanup_push() и pthread_cleanup_pop().
После того как выполнятся все обработчики завершения, в неспецифицированном порядке вызываются
Возможность дождаться завершения заданного потока управления
реализуется функцией pthread_join().
Помимо заказа на pthread_kill().
Полезная операция, связанная с обработкой завершения потока управления, – его pthread_detach().
Обратим внимание на то, что, согласно стандарту POSIX-2001,
функции, обслуживающие потоки управления, никогда не завершаются с
EINTR. Восстановление
нормального состояния после того, как
Функции, обслуживающие
pthread_mutex_init(),
pthread_mutex_destroy() ;pthread_mutex_lock(),
pthread_mutex_trylock(), pthread_mutex_timedlock(),
pthread_mutex_unlock() ;pthread_mutex_getprioceiling(), pthread_mutex_setprioceiling();
pthread_mutexattr_init(), pthread_mutexattr_destroy();
pthread_mutexattr_gettype(), pthread_mutexattr_settype(), pthread_mutexattr_getpshared(), pthread_mutexattr_setpshared(), pthread_mutexattr_getprotocol(), pthread_mutexattr_setprotocol(), pthread_mutexattr_getprioceiling(), pthread_mutexattr_setprioceiling();
Для инициализации статически описанных PTHREAD_MUTEX_INITIALIZER.
У инициализированного
pthread_mutexattr_gettype() и pthread_mutexattr_settype()) ;pthread_mutexattr_getprotocol(), pthread_mutexattr_setprotocol()) ;pthread_mutexattr_getpshared(), pthread_mutexattr_setpshared() ).В стандарте POSIX-2001 определены четыре типа
PTHREAD_MUTEX_NORMAL, PTHREAD_MUTEX_ERRORCHECK, PTHREAD_MUTEX_RECURSIVE, PTHREAD_MUTEX_DEFAULT.
Атрибут "протокол" влияет на PTHREAD_PRIO_NONE, PTHREAD_PRIO_INHERIT, PTHREAD_PRIO_PROTECT.
Пусть имеется некоторый предикат (условие), зависящий от значений переменных, разделяемых несколькими потоками управления.
Совместное использование
while (! предикат) {
Ожидание на переменной условия с освобождением мьютекса.
После успешного завершения ожидания поток вновь
оказывается владельцем мьютекса.
}
После нормального выхода из цикла проверяемое условие истинно;
можно выполнить требуемые действия и освободить
Разблокирование потоков управления, ожидающих на переменной условия, должен обеспечить другой поток, изменивший значения разделяемых переменных и отправивший ждущим соответствующее уведомление.
Функции, предлагаемые стандартом POSIX-2001 для обслуживания
pthread_cond_init(), pthread_cond_destroy();
pthread_cond_wait(), pthread_cond_timedwait();
pthread_cond_broadcast(),
pthread_cond_signal() ;pthread_condattr_init(), pthread_condattr_destroy() ;pthread_condattr_getpshared(),
pthread_condattr_setpshared() ) и идентификатора часов реального времени, используемых для ограничения ожидания на pthread_condattr_getclock(),
pthread_condattr_setclock().Применительно к
pthread_rwlock_init(), pthread_rwlock_destroy();
pthread_rwlock_rdlock(),
pthread_rwlock_tryrdlock(), pthread_rwlock_timedrdlock() ;pthread_rwlock_wrlock(),
pthread_rwlock_trywrlock(), pthread_rwlock_timedwrlock() ;pthread_rwlock_unlock() ;pthread_rwlockattr_init(), pthread_rwlockattr_destroy();
pthread_rwlockattr_getpshared(), pthread_rwlockattr_setpshared().
Согласно стандарту POSIX-2001,
pthread_spin_init(), pthread_spin_destroy();
pthread_spin_lock(),
pthread_spin_trylock() ;pthread_spin_unlock().Функции, ассоциированные с
pthread_barrier_init(),
pthread_barrier_destroy() ;pthread_barrier_wait() ;pthread_barrierattr_init(), pthread_barrierattr_destroy();
pthread_barrierattr_getpshared(), pthread_barrierattr_setpshared().Когда к функции
pthread_barrier_wait() обратилось требуемое
число потоков управления, одному из них (стандарт POSIX-2001 не специфицирует, какому именно) в качестве результата возвращается именованная константа PTHREAD_BARRIER_SERIAL_THREAD, а всем другим достаются
нули. После этого При стандартизации средств одношагового порождения
Чтобы достичь перечисленных целей, функции posix_spawn() и posix_spawnp() контролируют шесть видов наследуемых сущностей:
Как правило, все открытые дескрипторы родительского FD_CLOEXEC. Кроме того, принимается во внимание
объект типа posix_spawn_file_actions_t, который содержит действия
по закрытию, открытию и/или дублированию файловых дескрипторов.
Для формирования объектов типа posix_spawn_file_actions_t служат
функции posix_spawn_file_actions_addclose(), posix_spawn_file_actions_addopen() и posix_spawn_file_actions_adddup2().
За контроль других сущностей, наследуемых при одношаговом порождении posix_spawnattr_init(),
posix_spawnattr_destroy(), posix_spawnattr_getflags(),
posix_spawnattr_setflags(), posix_spawnattr_getpgroup(),
posix_spawnattr_setpgroup(), posix_spawnattr_getschedparam(),
posix_spawnattr_setschedparam(), posix_spawnattr_getschedpolicy(),
posix_spawnattr_setschedpolicy(), posix_spawnattr_getsigdefault(),
posix_spawnattr_setsigdefault(), posix_spawnattr_getsigmask(),
posix_spawnattr_setsigmask().
Реализация одношагового порождения . Естественно,
надеяться на повышение эффективности по сравнению с двухшаговым
порождением имеет смысл только в первом случае.
Приложениям реального времени требуются средства надежного,
детерминированного, асинхронного извещения (
Номера сигналов реального времени лежат в диапазоне от SIGRTMIN
до SIGRTMAX. Всего таких сигналов должно быть не меньше, чем RTSIG_MAX.
"Жизненный цикл" сигналов реального времени состоит из четырех фаз:
Сигналы реального времени могут генерироваться при срабатывании высокоточных sigqueue() и т.д.
На фазе генерации сигналов центральную роль играет структура типа sigevent, которая, помимо прочего, определяет способ уведомления и
значение сигнала.
Стандартом POSIX-2001 предусмотрено три способа уведомления об
асинхронных событиях: SIGEV_NONE (отсутствие уведомления), SIGEV_SIGNAL (SIGEV_THREAD (вызов функции).
Значение сигнала реального времени может быть целым числом или указателем.
Сгенерировать сигнал реального времени можно, обратившись к
функции sigqueue().
После того, как сигнал сгенерирован, наступает фаза ожидания.
Сигналы одного типа ставятся в очередь к
Дождаться sigwaitinfo() и sigtimedwait().
При наличии нескольких неблокированных ждущих сигналов реального времени, их доставка
Для приложений реального времени, функционирующих на аппаратных конфигурациях с ограниченными ресурсами, может оказаться полезной возможность (распространяющаяся на все сигналы) выполнять
функции обработки сигналов не на основном, а на sigaltstack() позволяет установить и/или опросить характеристики
Обработка сигналов (не обязательно реального времени) нередко сочетается с sigsetjmp() и siglongjmp().
Стандартом POSIX-2001 предусмотрены средства, позволяющие создавать для
Чтобы создать для timer_create().
Для удаления timer_delete().
Для выполнения содержательных действий с timer_gettime(), timer_settime() и timer_getoverrun().
Отметим, что наличие функции timer_getoverrun() позволяет избавиться от неопределенно большого расхода ресурсов на постановку в
очередь сигналов реального времени, которые
Для приложений реального времени важна возможность использования не только процессорных, но и монотонных часов. В основном из
этих соображений в стандарте POSIX-2001 присутствует расширенный
аналог рассмотренной в курсе [1] функции nanosleep() – clock_nanosleep().
Над описанными в настоящем курсе очередями сообщений определены следующие группы функций:
Для открытия очереди служит функция mq_open(). Одну очередь
могут открыть несколько посылающих и/или принимающих сообщения
Отправка осуществляется функциями mq_send() и mq_timedsend().
Для извлечения сообщений из очереди служат функции mq_receive() и mq_timedreceive(). На порядок приема влияет имеющийся механизм
Для опроса и/или mq_getattr() и mq_setattr(). Для каждой очереди задается фиксированная
Посредством функции mq_notify()
После того, как mq_close().
Очередь сообщений можно удалить с помощью функции mq_unlink().
Семафор реального времени – это эффективный
Основными операциями над семафором являются
Если при освобождении семафора множество ждущих потоков было
непусто, один из них удаляется из этого множества и его выполнение возобновляется; в противном случае
Семафоры бывают именованными и безымянными. Первые именуются цепочками символов и создаются функцией sem_open() с флагом O_CREAT, вторые создаются функцией sem_init().
sem_close(), и удалить с помощью функции sem_unlink() ; для ликвидации sem_destroy().
Для sem_wait(), sem_trywait()
и sem_timedwait().
sem_post().
Функция sem_getvalue() позволяет опросить
Необходимо отметить, что описание семафоров реального времени в
стандарте POSIX-2001 внутренне противоречиво. В большинстве мест явно
написано, что семафоры эти целочисленные; в то же время, из описания
функции sem_wait() следует, что имеются в виду
Механизм объектов в памяти служит цели минимизации времени и унификации доступа. Стандартом POSIX-2001 предусмотрено три вида таких объектов:
Рассматриваемый класс средств базируется на идее отображения
объекта в
Отображаться могут обычные файлы, а также объекты в разделяемой и типизированной памяти.
Отображение объектов в mmap().
Стандарт POSIX-2001 предусматривает возможность динамической
смены разрешенных видов доступа к отображенным страницам посредством вызова функции mprotect().
Для munmap().
При работе с объектами в памяти полезны функции truncate() и ftruncate(), позволяющие установить размер объекта равным заданной
величине.
Еще одна возможность, полезная в связи с отображением объектов в msync().
Стандартизованный программный интерфейс к shm_open() для открытия (возможно, с
созданием) подобного объекта и получения его дескриптора, а также shm_unlink() для удаления ранее созданного объекта.
Каждая допустимая комбинация пула памяти и порта идентифицируется именем, определяемым при конфигурировании системы способом,
зависящим от реализации. Используя это имя, объект в типизированной
памяти можно открыть при помощи функции posix_typed_mem_open(), а
затем отобразить в
После того, как posix_typed_mem_get_info() можно выяснить максимальный объем памяти, доступной для резервирования.
Функция posix_mem_offset() позволяет выяснить адрес (смещение
от начала), длину и дескриптор объекта (блока) в типизированной памяти, отображенного в
Для повышения детерминированности
Для удержания в физической памяти группы страниц из адресного
пространства mlock().
Удержание отменяется после вызовов и exec(), а также в результате ликвидации по какой-либо причине соответствующей части адресного пространства munlock().
Если нужно удерживать в памяти все mlockall() и munlockall().
У каждого потока управления (
Цель политики планирования состоит в определении допустимых операций над множеством списков (например, перемещение потоков между списками и внутри них).
Реализация, удовлетворяющая стандарту POSIX, должна выбирать
для выполнения
Политика SCHED_FIFO (
Чтобы сделать SCHED_RR (циклическое SCHED_FIFO с
одним исключением: когда время, в течение которого sched_rr_get_interval(), он перемещается в хвост соответствующего
списка, а для выполнения выбирается головной поток. Таким образом, ни
один из равноприоритетных потоков не сможет монополизировать процессор.
По сравнению с SCHED_FIFO и SCHED_RR, политика SCHED_SPORADIC
(спорадическое
Четвертая SCHED_OTHER ). Она необходима, чтобы мобильные приложения могли заявить, что они больше не нуждаются в политике планирования реального
времени.
Стандарт POSIX-2001 предусматривает следующие функции управления sched_getscheduler() (опрос политики
планирования sched_getparam() (sched_setscheduler() (установка политики и sched_setparam() (установка параметров
планирования
Стандарт POSIX-2001 предоставляет также средства для опроса характеристик sched_get_priority_min() )
и максимального ( sched_get_priority_max() ) среди допустимых приоритетов, а также величины кванта выделяемого процессорного времени
для политики sched_rr_get_interval() ).
Функция sched_yield() позволяет вызывающему потоку управления добровольно уступить процессор.
Средства асинхронного ввода/вывода позволяют прикладным
После завершения асинхронной операции ввода/вывода приложению может быть доставлен сигнал.
Жизненный цикл операции асинхронного ввода/вывода включает два этапа:
Основными операциями асинхронного ввода/вывода являются
чтение ( aio_read() ) и запись ( aio_write() ) данных.
Функция lio_listio() позволяет за один вызов поставить в очередь
Для выяснения статуса операций асинхронного ввода/вывода служат функции aio_return() и aio_error().
Ожидающие обработки запросы на асинхронный ввод/вывод можно
аннулировать, воспользовавшись функцией aio_cancel().
Согласно стандарту POSIX-2001, списком можно не только инициировать запросы на асинхронный ввод/вывод, но и ожидать их завершения. Для этого служит функция aio_suspend().
Функции , fsync(), fdatasync(), aio_fsync() предназначены для согласования состояния буферизованных и хранимых в долговременной памяти данных, обеспечения целостности данных и файлов.
В стандарте POSIX-2001 предусмотрена
Описанные возможности реализуют функции posix_fadvise(), posix_fallocate(), posix_madvise() и posix_memalign().
Ожидаемое поведение может специфицироваться как:
При оптимизации обмена данными с файлами, наряду с применением
POSIX_REC_MIN_XFER_SIZE
Минимальное рекомендуемое число передаваемых байт при обмене
данными с файлами. Рекомендуется также, чтобы и смещение передаваемой
порции данных от начала файла было кратным POSIX_REC_MIN_XFER_SIZE.
POSIX_REC_MAX_XFER_SIZE
Максимальное рекомендуемое число передаваемых байт при обмене данными с файлами.
POSIX_REC_XFER_ALIGN
Рекомендуемое значение для выравнивания границы буфера обмена данными с файлами.
С логической точки зрения в трассировке участвуют три
Сведения о действиях, производимых при выполнении приложения,
фиксируются в виде объектов данных, называемых событиями трассировки. События записываются в
Трассируемый
События трассировки подразделяются на две категории:
posix_trace_event().
У событий трассировки есть типы и имена, между которыми устанавливается взаимно-однозначное соответствие.
Стандартом POSIX-2001 предусмотрен механизм фильтрации, позволяющий отключить генерацию событий определенных типов и, тем самым, уменьшать объем трассировочных данных.
И для потоков, и для журналов трассировки правила обработки ситуации заполнения могут сводиться к записи новых событий поверх самых старых или к
При
Для создания и уничтожения posix_trace_attr_init() и posix_trace_attr_destroy().
Для манипулирования атрибутами, идентифицирующими поток
трассировки, служат функции posix_trace_attr_getgenversion(),
posix_trace_attr_getname(), posix_trace_attr_setname(),
posix_trace_attr_getcreatetime().
Функция posix_trace_attr_getclockres() позволяет опросить
разрешающую способность часов, с помощью которых проставляются
временные штампы.
posix_trace_attr_getinherited(),
posix_trace_attr_setinherited(),
posix_trace_attr_getstreamfullpolicy(),
posix_trace_attr_setstreamfullpolicy(),
posix_trace_attr_getlogfullpolicy(),
posix_trace_attr_setlogfullpolicy().
Опросить и установить хранящиеся в атрибутном объекте размеры
событий, потоков и журналов можно с помощью функций posix_trace_attr_getmaxdatasize(),
posix_trace_attr_setmaxdatasize(),
posix_trace_attr_getmaxsystemeventsize(),
posix_trace_attr_getmaxusereventsize(),
posix_trace_attr_getstreamsize(),
posix_trace_attr_setstreamsize(),
posix_trace_attr_getlogsize(),
posix_trace_attr_setlogsize().
Создание потока трассировки осуществляется функциями posix_trace_create() или posix_trace_create_withlog().
Чтобы активизировать трассировку, следует воспользоваться функцией posix_trace_start() ; для последующей приостановки нужно вызвать функцию posix_trace_stop().
Функция posix_trace_shutdown() завершает трассировку и освобождает ресурсы, ассоциированные с потоком.
По ходу трассировки управляющий posix_trace_flush().
Опрос posix_trace_get_status().
Стандартом POSIX-2001 предусмотрен posix_trace_get_attr().
Поток и posix_trace_clear().
При опросе и установке фильтров событий трассировки (функции posix_trace_get_filter() и posix_trace_set_filter() ) применяется
апробированная схема работы с множествами, основанная на функциях posix_trace_eventset_empty(), posix_trace_eventset_fill(),
posix_trace_eventset_add(), posix_trace_eventset_del(),
posix_trace_eventset_ismember().
Играющие техническую роль функции posix_trace_trid_eventid_open(), posix_trace_eventid_get_name()
и posix_trace_eventid_equal() обслуживают идентификаторы типов
событий, рассматриваемые как абстрактные объекты.
Функции posix_trace_eventtypelist_getnext_id() и posix_trace_eventtypelist_rewind() позволяют обрабатывать совокупность
Функция posix_trace_eventid_open() ассоциирует
Анализирующий posix_trace_open(), а обработав, закрывает его с
помощью функции posix_trace_close(), быть может, в промежутке позиционируясь на начало журнала посредством функции posix_trace_rewind(). Для чтения событий служат функции posix_trace_getnext_event(), posix_trace_timedgetnext_event() и posix_trace_trygetnext_event().
Для работы с системным журналом стандарт POSIX-2001 предлагает
функции записи сообщений ( syslog() ), установки фильтра (маски журналируемых сообщений, setlogmask() ) и других параметров журналирования ( openlog() ) и, наконец, завершения работы с системным журналом
( closelog() ).
У журналируемых сообщений имеются такие атрибуты, как уровень серьезности и источник.
К этой же прикладной области можно отнести служебную программу logger и функцию fmtmsg().
Стандартом POSIX-2001 предусмотрен набор функций для работы с
getutxent() ), getutxid(), getutxline() ), модификацию или добавление записей ( pututxline() ), возврат к началу ( setutxent() ) и завершение работы с базой ( endutxent() ).
Универсальный характер носят функции для работы с простыми базами данных. Подобную базу можно открыть ( dbm_open() ) и закрыть
( dbm_close() ), выбрать ( dbm_fetch() ), сохранить ( dbm_store() ) и удалить ( dbm_delete() ) запись по ключу, перебрать имеющиеся в базе ключи
( dbm_firstkey(), dbm_nextkey() ), опросить статус ошибки
( dbm_error() ) и очистить его ( dbm_clearerr() ).
Важный подкласс технологических интерфейсов образуют средства
Бинарный bsearch(), последовательный
– функциями lsearch() ( lfind(). Управление хэш-таблицами осуществляется посредством функций hcreate(), hdestroy() и hsearch(). Бинарные деревья tsearch()
( tfind(), tdelete() и twalk() (обход деревьев).
Для сортировки массивов целесообразно пользоваться функцией qsort(). Существует также служебная программа tsort.
Функции insque() и remque() реализуют вставку и удаление элементов очереди.
Согласно стандарту POSIX-2001, пользовательский контекст потока
управления включает содержимое машинных регистров, getcontext() ), модификации ( makecontext() ) и смены ( setcontext() и swapcontext() ) пользовательских контекстов.
Рассматриваемая в стандарте POSIX-2001 среда
Если приложение проверяет флаги состояния, устанавливает собственные управляющие режимы или выполняется в режимах, отличных от
подразумеваемого, то при компиляции необходимо воспользоваться управляющим комментарием (#pragma) FENV_ACCESS:
#pragma STDC FENV_ACCESS ON
Опросить и установить текущую fegetenv() и fesetenv().
Сохранение текущей среды может сочетаться с ее изменением.
Функция feholdexcept() очищает флаги состояния и устанавливает "безостановочный" режим, а feupdateenv() сохраняет в своей локальной памяти информацию о текущей исключительной ситуации, устанавливает
новую среду и затем пытается возбудить в ней сохраненное исключение.
Для опроса и установки флагов состояния стандартом POSIX-2001
предусмотрены функции fegetexceptflag() и fesetexceptflag().
Функции fetestexcept(), feclearexcept() и feraiseexcept()
служат, соответственно, для проверки, сброса и возбуждения исключительных ситуаций.
Опросить и установить режим округления можно с помощью функций fegetround() и fesetround().
Обход файловой иерархии – типовая задача, для решения которой
стандартом POSIX-2001 предлагаются две сходные функции – ftw() и nftw().
Служебная программа xargs дает возможность формировать и выполнять командные строки, объединяя зафиксированный набор начальных аргументов с аргументами, прочитанными со стандартного ввода.
В качестве последнего элемента технологических интерфейсов рассматриваются функции для работы с
В стандарте POSIX-2001 выстроена пятиэтапная модель получения
доступа к
posix_openpt() );unlockpt() );grantpt() );ptsname() );open() ).На этом мы завершаем описание средств программирования приложений в стандарте POSIX.
Настоящий курс является продолжением курса [1]. В принципе, разделение единой темы "Программирование в стандарте POSIX" на две части носит скорее технический, чем принципиальный характер, однако у
второй части есть свой стержень –
Основной структурной единицей приложения реального времени
является
Для задания характеристик потоков управления (и других рассматриваемых в настоящем курсе сущностей) в стандарте POSIX-2001 активно
используются
По отношению к потокам управления вводится понятие безопасных функций, которые можно вызывать параллельно в нескольких потоках без нарушения корректности их функционирования. К числу безопасных принадлежат "чистые" функции, а также функции, обеспечивающие взаимное исключение перед доступом к разделяемым объектам. Если в стандарте явно не оговорено противное, функция считается потоково-безопасной.
Для приложений реального времени исключительно важно и активно используется понятие планирования.
Под
Операции с потоками управления можно подразделить на две группы:
В таком порядке они и рассматриваются в настоящем курсе.
При анализе средств
Чтобы быть практически полезными, средства синхронизации, специально ориентированные на потоки управления, должны быть оптимизированы с учетом обеих отмеченных особенностей.
К числу таких средств, присутствующих в стандарте POSIX-2001,
принадлежат
Средства синхронизации могут использоваться для достижения двух существенно разных целей:
Тема "
Одношаговое порождение posix_spawn() и posix_spawnp().
Под сигналами реального времени понимается не нарушающее совместимости расширение общего механизма сигналов, повышающее детерминированность за счет постановки сигналов, асинхронно доставленных приложению, в очередь.
Основные понятия, ассоциированные с часами и
В качестве
Чтобы время доступа к объекту было по возможности минимальным
и не превышало заданной величины, этот объект делают резидентным в
физической памяти. Применительно к
Достижению той же цели – минимизации времени (а также унификации) доступа – служит механизм объектов в памяти.
Приоритетное
Средства асинхронного ввода/вывода позволяют прикладным
Приложения реального времени сложно не только разрабатывать, но и отлаживать, поскольку в понятие семантической корректности входит дополнительный компонент – соблюдение временных ограничений. Для решения этой проблемы в стандарте POSIX-2001 предусмотрен механизм трассировки.
Применительно к приложениям реального времени
В настоящем курсе рассматриваются также так называемые технологические интерфейсы, играющие техническую, подчиненную роль,
но необходимые для использования возможностей более высокого
уровня. К числу технологических интерфейсов отнесены функции и
утилиты для работы с системным журналом, функции для работы с
Таковы основные понятия и объекты, ставшие предметом рассмотрения в настоящем курсе.
В рамках любого pthread_self().
Порождению потоков управления обычно предшествует создание
pthread_attr_init().
Когда объект перестает быть нужным, его ликвидируют, вызывая pthread_attr_destroy().
В число поддерживаемых входят атрибуты стека (функции pthread_attr_getstack(), pthread_attr_setstack(),
pthread_attr_getguardsize(), pthread_attr_setguardsize()),
планирования (pthread_attr_getschedparam(),
pthread_attr_setschedparam(), pthread_attr_getschedpolicy(),
pthread_attr_setschedpolicy(), pthread_attr_getscope(),
pthread_attr_setscope(), pthread_attr_getinheritsched(),
pthread_attr_setinheritsched() ) и обособленности
( pthread_attr_getdetachstate(), pthread_attr_setdetachstate() ).
Обратим внимание на средство
Значения атрибутов планирования могут задаваться не только при
создании потока управления. Стандарт POSIX-2001 предоставляет средства для их динамического изменения и опроса – функции pthread_getschedparam(), pthread_setschedparam(),
pthread_setschedprio(), pthread_getconcurrency(),
pthread_setconcurrency().
К числу pthread_getcpuclockid().
Еще один атрибут потока управления – pthread_sigmask().
Все потоки управления одного pthread_key_create() создать ключ и ассоциировать с ним индивидуальные данные, воспользовавшись функцией pthread_setspecific().
В дальнейшем эти данные можно извлекать посредством функции pthread_getspecific(). Подчеркнем, что при обращении по одному
(разделяемому) ключу разные потоки будут получать доступ к разным
данным.
Создать один ключ, очевидно, нужно один раз. Для решения проблемы однократного выполнения pthread_once().
За удаление ключа pthread_key_delete().
Модель порождения потоков управления отличается от соответствующей модели для создающий поток должен обратиться лишь к одной функции – pthread_create().
От "родительского" вновь созданный
К числу средств создания потоков можно отнести и функцию . С ней можно ассоциировать обработчики, зарегистрировав их с
помощью функции pthread_atfork(). В каждом обращении к pthread_atfork() фигурируют три обработчика. Первый выполняется в
контексте потока, вызвавшего , до разветвления
pthread_exit().
Заказать pthread_cancel().
На выполнение "заказа" влияют состояние восприимчивости к
терминированию (разрешено/запрещено) и pthread_setcancelstate(), pthread_setcanceltype() и pthread_testcancel().
Стандартом POSIX-2001 предусмотрено существование pthread_cleanup_push() и pthread_cleanup_pop().
После того как выполнятся все обработчики завершения, в неспецифицированном порядке вызываются
Возможность дождаться завершения заданного потока управления
реализуется функцией pthread_join().
Помимо заказа на pthread_kill().
Полезная операция, связанная с обработкой завершения потока управления, – его pthread_detach().
Обратим внимание на то, что, согласно стандарту POSIX-2001,
функции, обслуживающие потоки управления, никогда не завершаются с
EINTR. Восстановление
нормального состояния после того, как
Функции, обслуживающие
pthread_mutex_init(),
pthread_mutex_destroy() ;pthread_mutex_lock(),
pthread_mutex_trylock(), pthread_mutex_timedlock(),
pthread_mutex_unlock() ;pthread_mutex_getprioceiling(), pthread_mutex_setprioceiling();
pthread_mutexattr_init(), pthread_mutexattr_destroy();
pthread_mutexattr_gettype(), pthread_mutexattr_settype(), pthread_mutexattr_getpshared(), pthread_mutexattr_setpshared(), pthread_mutexattr_getprotocol(), pthread_mutexattr_setprotocol(), pthread_mutexattr_getprioceiling(), pthread_mutexattr_setprioceiling();
Для инициализации статически описанных PTHREAD_MUTEX_INITIALIZER.
У инициализированного
pthread_mutexattr_gettype() и pthread_mutexattr_settype()) ;pthread_mutexattr_getprotocol(), pthread_mutexattr_setprotocol()) ;pthread_mutexattr_getpshared(), pthread_mutexattr_setpshared() ).В стандарте POSIX-2001 определены четыре типа
PTHREAD_MUTEX_NORMAL, PTHREAD_MUTEX_ERRORCHECK, PTHREAD_MUTEX_RECURSIVE, PTHREAD_MUTEX_DEFAULT.
Атрибут "протокол" влияет на PTHREAD_PRIO_NONE, PTHREAD_PRIO_INHERIT, PTHREAD_PRIO_PROTECT.
Пусть имеется некоторый предикат (условие), зависящий от значений переменных, разделяемых несколькими потоками управления.
Совместное использование
while (! предикат) {
Ожидание на переменной условия с освобождением мьютекса.
После успешного завершения ожидания поток вновь
оказывается владельцем мьютекса.
}
После нормального выхода из цикла проверяемое условие истинно;
можно выполнить требуемые действия и освободить
Разблокирование потоков управления, ожидающих на переменной условия, должен обеспечить другой поток, изменивший значения разделяемых переменных и отправивший ждущим соответствующее уведомление.
Функции, предлагаемые стандартом POSIX-2001 для обслуживания
pthread_cond_init(), pthread_cond_destroy();
pthread_cond_wait(), pthread_cond_timedwait();
pthread_cond_broadcast(),
pthread_cond_signal() ;pthread_condattr_init(), pthread_condattr_destroy() ;pthread_condattr_getpshared(),
pthread_condattr_setpshared() ) и идентификатора часов реального времени, используемых для ограничения ожидания на pthread_condattr_getclock(),
pthread_condattr_setclock().Применительно к
pthread_rwlock_init(), pthread_rwlock_destroy();
pthread_rwlock_rdlock(),
pthread_rwlock_tryrdlock(), pthread_rwlock_timedrdlock() ;pthread_rwlock_wrlock(),
pthread_rwlock_trywrlock(), pthread_rwlock_timedwrlock() ;pthread_rwlock_unlock() ;pthread_rwlockattr_init(), pthread_rwlockattr_destroy();
pthread_rwlockattr_getpshared(), pthread_rwlockattr_setpshared().
Согласно стандарту POSIX-2001,
pthread_spin_init(), pthread_spin_destroy();
pthread_spin_lock(),
pthread_spin_trylock() ;pthread_spin_unlock().Функции, ассоциированные с
pthread_barrier_init(),
pthread_barrier_destroy() ;pthread_barrier_wait() ;pthread_barrierattr_init(), pthread_barrierattr_destroy();
pthread_barrierattr_getpshared(), pthread_barrierattr_setpshared().Когда к функции
pthread_barrier_wait() обратилось требуемое
число потоков управления, одному из них (стандарт POSIX-2001 не специфицирует, какому именно) в качестве результата возвращается именованная константа PTHREAD_BARRIER_SERIAL_THREAD, а всем другим достаются
нули. После этого При стандартизации средств одношагового порождения
Чтобы достичь перечисленных целей, функции posix_spawn() и posix_spawnp() контролируют шесть видов наследуемых сущностей:
Как правило, все открытые дескрипторы родительского FD_CLOEXEC. Кроме того, принимается во внимание
объект типа posix_spawn_file_actions_t, который содержит действия
по закрытию, открытию и/или дублированию файловых дескрипторов.
Для формирования объектов типа posix_spawn_file_actions_t служат
функции posix_spawn_file_actions_addclose(), posix_spawn_file_actions_addopen() и posix_spawn_file_actions_adddup2().
За контроль других сущностей, наследуемых при одношаговом порождении posix_spawnattr_init(),
posix_spawnattr_destroy(), posix_spawnattr_getflags(),
posix_spawnattr_setflags(), posix_spawnattr_getpgroup(),
posix_spawnattr_setpgroup(), posix_spawnattr_getschedparam(),
posix_spawnattr_setschedparam(), posix_spawnattr_getschedpolicy(),
posix_spawnattr_setschedpolicy(), posix_spawnattr_getsigdefault(),
posix_spawnattr_setsigdefault(), posix_spawnattr_getsigmask(),
posix_spawnattr_setsigmask().
Реализация одношагового порождения . Естественно,
надеяться на повышение эффективности по сравнению с двухшаговым
порождением имеет смысл только в первом случае.
Приложениям реального времени требуются средства надежного,
детерминированного, асинхронного извещения (
Номера сигналов реального времени лежат в диапазоне от SIGRTMIN
до SIGRTMAX. Всего таких сигналов должно быть не меньше, чем RTSIG_MAX.
"Жизненный цикл" сигналов реального времени состоит из четырех фаз:
Сигналы реального времени могут генерироваться при срабатывании высокоточных sigqueue() и т.д.
На фазе генерации сигналов центральную роль играет структура типа sigevent, которая, помимо прочего, определяет способ уведомления и
значение сигнала.
Стандартом POSIX-2001 предусмотрено три способа уведомления об
асинхронных событиях: SIGEV_NONE (отсутствие уведомления), SIGEV_SIGNAL (SIGEV_THREAD (вызов функции).
Значение сигнала реального времени может быть целым числом или указателем.
Сгенерировать сигнал реального времени можно, обратившись к
функции sigqueue().
После того, как сигнал сгенерирован, наступает фаза ожидания.
Сигналы одного типа ставятся в очередь к
Дождаться sigwaitinfo() и sigtimedwait().
При наличии нескольких неблокированных ждущих сигналов реального времени, их доставка
Для приложений реального времени, функционирующих на аппаратных конфигурациях с ограниченными ресурсами, может оказаться полезной возможность (распространяющаяся на все сигналы) выполнять
функции обработки сигналов не на основном, а на sigaltstack() позволяет установить и/или опросить характеристики
Обработка сигналов (не обязательно реального времени) нередко сочетается с sigsetjmp() и siglongjmp().
Стандартом POSIX-2001 предусмотрены средства, позволяющие создавать для
Чтобы создать для timer_create().
Для удаления timer_delete().
Для выполнения содержательных действий с timer_gettime(), timer_settime() и timer_getoverrun().
Отметим, что наличие функции timer_getoverrun() позволяет избавиться от неопределенно большого расхода ресурсов на постановку в
очередь сигналов реального времени, которые
Для приложений реального времени важна возможность использования не только процессорных, но и монотонных часов. В основном из
этих соображений в стандарте POSIX-2001 присутствует расширенный
аналог рассмотренной в курсе [1] функции nanosleep() – clock_nanosleep().
Над описанными в настоящем курсе очередями сообщений определены следующие группы функций:
Для открытия очереди служит функция mq_open(). Одну очередь
могут открыть несколько посылающих и/или принимающих сообщения
Отправка осуществляется функциями mq_send() и mq_timedsend().
Для извлечения сообщений из очереди служат функции mq_receive() и mq_timedreceive(). На порядок приема влияет имеющийся механизм
Для опроса и/или mq_getattr() и mq_setattr(). Для каждой очереди задается фиксированная
Посредством функции mq_notify()
После того, как mq_close().
Очередь сообщений можно удалить с помощью функции mq_unlink().
Семафор реального времени – это эффективный
Основными операциями над семафором являются
Если при освобождении семафора множество ждущих потоков было
непусто, один из них удаляется из этого множества и его выполнение возобновляется; в противном случае
Семафоры бывают именованными и безымянными. Первые именуются цепочками символов и создаются функцией sem_open() с флагом O_CREAT, вторые создаются функцией sem_init().
sem_close(), и удалить с помощью функции sem_unlink() ; для ликвидации sem_destroy().
Для sem_wait(), sem_trywait()
и sem_timedwait().
sem_post().
Функция sem_getvalue() позволяет опросить
Необходимо отметить, что описание семафоров реального времени в
стандарте POSIX-2001 внутренне противоречиво. В большинстве мест явно
написано, что семафоры эти целочисленные; в то же время, из описания
функции sem_wait() следует, что имеются в виду
Механизм объектов в памяти служит цели минимизации времени и унификации доступа. Стандартом POSIX-2001 предусмотрено три вида таких объектов:
Рассматриваемый класс средств базируется на идее отображения
объекта в
Отображаться могут обычные файлы, а также объекты в разделяемой и типизированной памяти.
Отображение объектов в mmap().
Стандарт POSIX-2001 предусматривает возможность динамической
смены разрешенных видов доступа к отображенным страницам посредством вызова функции mprotect().
Для munmap().
При работе с объектами в памяти полезны функции truncate() и ftruncate(), позволяющие установить размер объекта равным заданной
величине.
Еще одна возможность, полезная в связи с отображением объектов в msync().
Стандартизованный программный интерфейс к shm_open() для открытия (возможно, с
созданием) подобного объекта и получения его дескриптора, а также shm_unlink() для удаления ранее созданного объекта.
Каждая допустимая комбинация пула памяти и порта идентифицируется именем, определяемым при конфигурировании системы способом,
зависящим от реализации. Используя это имя, объект в типизированной
памяти можно открыть при помощи функции posix_typed_mem_open(), а
затем отобразить в
После того, как posix_typed_mem_get_info() можно выяснить максимальный объем памяти, доступной для резервирования.
Функция posix_mem_offset() позволяет выяснить адрес (смещение
от начала), длину и дескриптор объекта (блока) в типизированной памяти, отображенного в
Для повышения детерминированности
Для удержания в физической памяти группы страниц из адресного
пространства mlock().
Удержание отменяется после вызовов и exec(), а также в результате ликвидации по какой-либо причине соответствующей части адресного пространства munlock().
Если нужно удерживать в памяти все mlockall() и munlockall().
У каждого потока управления (
Цель политики планирования состоит в определении допустимых операций над множеством списков (например, перемещение потоков между списками и внутри них).
Реализация, удовлетворяющая стандарту POSIX, должна выбирать
для выполнения
Политика SCHED_FIFO (
Чтобы сделать SCHED_RR (циклическое SCHED_FIFO с
одним исключением: когда время, в течение которого sched_rr_get_interval(), он перемещается в хвост соответствующего
списка, а для выполнения выбирается головной поток. Таким образом, ни
один из равноприоритетных потоков не сможет монополизировать процессор.
По сравнению с SCHED_FIFO и SCHED_RR, политика SCHED_SPORADIC
(спорадическое
Четвертая SCHED_OTHER ). Она необходима, чтобы мобильные приложения могли заявить, что они больше не нуждаются в политике планирования реального
времени.
Стандарт POSIX-2001 предусматривает следующие функции управления sched_getscheduler() (опрос политики
планирования sched_getparam() (sched_setscheduler() (установка политики и sched_setparam() (установка параметров
планирования
Стандарт POSIX-2001 предоставляет также средства для опроса характеристик sched_get_priority_min() )
и максимального ( sched_get_priority_max() ) среди допустимых приоритетов, а также величины кванта выделяемого процессорного времени
для политики sched_rr_get_interval() ).
Функция sched_yield() позволяет вызывающему потоку управления добровольно уступить процессор.
Средства асинхронного ввода/вывода позволяют прикладным
После завершения асинхронной операции ввода/вывода приложению может быть доставлен сигнал.
Жизненный цикл операции асинхронного ввода/вывода включает два этапа:
Основными операциями асинхронного ввода/вывода являются
чтение ( aio_read() ) и запись ( aio_write() ) данных.
Функция lio_listio() позволяет за один вызов поставить в очередь
Для выяснения статуса операций асинхронного ввода/вывода служат функции aio_return() и aio_error().
Ожидающие обработки запросы на асинхронный ввод/вывод можно
аннулировать, воспользовавшись функцией aio_cancel().
Согласно стандарту POSIX-2001, списком можно не только инициировать запросы на асинхронный ввод/вывод, но и ожидать их завершения. Для этого служит функция aio_suspend().
Функции , fsync(), fdatasync(), aio_fsync() предназначены для согласования состояния буферизованных и хранимых в долговременной памяти данных, обеспечения целостности данных и файлов.
В стандарте POSIX-2001 предусмотрена
Описанные возможности реализуют функции posix_fadvise(), posix_fallocate(), posix_madvise() и posix_memalign().
Ожидаемое поведение может специфицироваться как:
При оптимизации обмена данными с файлами, наряду с применением
POSIX_REC_MIN_XFER_SIZE
Минимальное рекомендуемое число передаваемых байт при обмене
данными с файлами. Рекомендуется также, чтобы и смещение передаваемой
порции данных от начала файла было кратным POSIX_REC_MIN_XFER_SIZE.
POSIX_REC_MAX_XFER_SIZE
Максимальное рекомендуемое число передаваемых байт при обмене данными с файлами.
POSIX_REC_XFER_ALIGN
Рекомендуемое значение для выравнивания границы буфера обмена данными с файлами.
С логической точки зрения в трассировке участвуют три
Сведения о действиях, производимых при выполнении приложения,
фиксируются в виде объектов данных, называемых событиями трассировки. События записываются в
Трассируемый
События трассировки подразделяются на две категории:
posix_trace_event().
У событий трассировки есть типы и имена, между которыми устанавливается взаимно-однозначное соответствие.
Стандартом POSIX-2001 предусмотрен механизм фильтрации, позволяющий отключить генерацию событий определенных типов и, тем самым, уменьшать объем трассировочных данных.
И для потоков, и для журналов трассировки правила обработки ситуации заполнения могут сводиться к записи новых событий поверх самых старых или к
При
Для создания и уничтожения posix_trace_attr_init() и posix_trace_attr_destroy().
Для манипулирования атрибутами, идентифицирующими поток
трассировки, служат функции posix_trace_attr_getgenversion(),
posix_trace_attr_getname(), posix_trace_attr_setname(),
posix_trace_attr_getcreatetime().
Функция posix_trace_attr_getclockres() позволяет опросить
разрешающую способность часов, с помощью которых проставляются
временные штампы.
posix_trace_attr_getinherited(),
posix_trace_attr_setinherited(),
posix_trace_attr_getstreamfullpolicy(),
posix_trace_attr_setstreamfullpolicy(),
posix_trace_attr_getlogfullpolicy(),
posix_trace_attr_setlogfullpolicy().
Опросить и установить хранящиеся в атрибутном объекте размеры
событий, потоков и журналов можно с помощью функций posix_trace_attr_getmaxdatasize(),
posix_trace_attr_setmaxdatasize(),
posix_trace_attr_getmaxsystemeventsize(),
posix_trace_attr_getmaxusereventsize(),
posix_trace_attr_getstreamsize(),
posix_trace_attr_setstreamsize(),
posix_trace_attr_getlogsize(),
posix_trace_attr_setlogsize().
Создание потока трассировки осуществляется функциями posix_trace_create() или posix_trace_create_withlog().
Чтобы активизировать трассировку, следует воспользоваться функцией posix_trace_start() ; для последующей приостановки нужно вызвать функцию posix_trace_stop().
Функция posix_trace_shutdown() завершает трассировку и освобождает ресурсы, ассоциированные с потоком.
По ходу трассировки управляющий posix_trace_flush().
Опрос posix_trace_get_status().
Стандартом POSIX-2001 предусмотрен posix_trace_get_attr().
Поток и posix_trace_clear().
При опросе и установке фильтров событий трассировки (функции posix_trace_get_filter() и posix_trace_set_filter() ) применяется
апробированная схема работы с множествами, основанная на функциях posix_trace_eventset_empty(), posix_trace_eventset_fill(),
posix_trace_eventset_add(), posix_trace_eventset_del(),
posix_trace_eventset_ismember().
Играющие техническую роль функции posix_trace_trid_eventid_open(), posix_trace_eventid_get_name()
и posix_trace_eventid_equal() обслуживают идентификаторы типов
событий, рассматриваемые как абстрактные объекты.
Функции posix_trace_eventtypelist_getnext_id() и posix_trace_eventtypelist_rewind() позволяют обрабатывать совокупность
Функция posix_trace_eventid_open() ассоциирует
Анализирующий posix_trace_open(), а обработав, закрывает его с
помощью функции posix_trace_close(), быть может, в промежутке позиционируясь на начало журнала посредством функции posix_trace_rewind(). Для чтения событий служат функции posix_trace_getnext_event(), posix_trace_timedgetnext_event() и posix_trace_trygetnext_event().
Для работы с системным журналом стандарт POSIX-2001 предлагает
функции записи сообщений ( syslog() ), установки фильтра (маски журналируемых сообщений, setlogmask() ) и других параметров журналирования ( openlog() ) и, наконец, завершения работы с системным журналом
( closelog() ).
У журналируемых сообщений имеются такие атрибуты, как уровень серьезности и источник.
К этой же прикладной области можно отнести служебную программу logger и функцию fmtmsg().
Стандартом POSIX-2001 предусмотрен набор функций для работы с
getutxent() ), getutxid(), getutxline() ), модификацию или добавление записей ( pututxline() ), возврат к началу ( setutxent() ) и завершение работы с базой ( endutxent() ).
Универсальный характер носят функции для работы с простыми базами данных. Подобную базу можно открыть ( dbm_open() ) и закрыть
( dbm_close() ), выбрать ( dbm_fetch() ), сохранить ( dbm_store() ) и удалить ( dbm_delete() ) запись по ключу, перебрать имеющиеся в базе ключи
( dbm_firstkey(), dbm_nextkey() ), опросить статус ошибки
( dbm_error() ) и очистить его ( dbm_clearerr() ).
Важный подкласс технологических интерфейсов образуют средства
Бинарный bsearch(), последовательный
– функциями lsearch() ( lfind(). Управление хэш-таблицами осуществляется посредством функций hcreate(), hdestroy() и hsearch(). Бинарные деревья tsearch()
( tfind(), tdelete() и twalk() (обход деревьев).
Для сортировки массивов целесообразно пользоваться функцией qsort(). Существует также служебная программа tsort.
Функции insque() и remque() реализуют вставку и удаление элементов очереди.
Согласно стандарту POSIX-2001, пользовательский контекст потока
управления включает содержимое машинных регистров, getcontext() ), модификации ( makecontext() ) и смены ( setcontext() и swapcontext() ) пользовательских контекстов.
Рассматриваемая в стандарте POSIX-2001 среда
Если приложение проверяет флаги состояния, устанавливает собственные управляющие режимы или выполняется в режимах, отличных от
подразумеваемого, то при компиляции необходимо воспользоваться управляющим комментарием (#pragma) FENV_ACCESS:
#pragma STDC FENV_ACCESS ON
Опросить и установить текущую fegetenv() и fesetenv().
Сохранение текущей среды может сочетаться с ее изменением.
Функция feholdexcept() очищает флаги состояния и устанавливает "безостановочный" режим, а feupdateenv() сохраняет в своей локальной памяти информацию о текущей исключительной ситуации, устанавливает
новую среду и затем пытается возбудить в ней сохраненное исключение.
Для опроса и установки флагов состояния стандартом POSIX-2001
предусмотрены функции fegetexceptflag() и fesetexceptflag().
Функции fetestexcept(), feclearexcept() и feraiseexcept()
служат, соответственно, для проверки, сброса и возбуждения исключительных ситуаций.
Опросить и установить режим округления можно с помощью функций fegetround() и fesetround().
Обход файловой иерархии – типовая задача, для решения которой
стандартом POSIX-2001 предлагаются две сходные функции – ftw() и nftw().
Служебная программа xargs дает возможность формировать и выполнять командные строки, объединяя зафиксированный набор начальных аргументов с аргументами, прочитанными со стандартного ввода.
В качестве последнего элемента технологических интерфейсов рассматриваются функции для работы с
В стандарте POSIX-2001 выстроена пятиэтапная модель получения
доступа к
posix_openpt() );unlockpt() );grantpt() );ptsname() );open() ).На этом мы завершаем описание средств программирования приложений в стандарте POSIX.
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.