Главная » 2017 » Ноябрь » 21 » man 2 nanosleep
01:03
man 2 nanosleep

SEO sprint - Всё для максимальной раскрутки!





ИМЯ


nanosleep - остановка работы процесса с более точным указанием периода



ОБЗОР


#include <time.h>

int nanosleep(const struct timespec *req, struct timespec *rem);

Требования макроса тестирования свойств для glibc (см. feature_test_macros(7)):

nanosleep(): _POSIX_C_SOURCE >= 199309L



ОПИСАНИЕ


nanosleep() приостанавливает работу вызывающей нити как минимум на время, заданное
параметром *req, или до получения сигнала, который вызовет обработчик в вызывающей
нити, или приведёт к завершению процесса.

Если вызов прерван обработчиком сигнала, то nanosleep() возвращает -1,
устанавливает errno в значение EINTR и записывает оставшееся время в структуру, на
которую указывает rem, если значение rem не равно NULL. Значение *rem можно
использовать для повторения вызова nanosleep() и продления окончания ожидания
интервала (но см. ЗАМЕЧАНИЯ).

Структура timespec позволяет задавать интервалы времени с точностью до
наносекунды. Она определена следующим образом:

struct timespec {
time_t tv_sec; /* секунды */
long tv_nsec; /* наносекунды */
};

Значение поля наносекунд должно находиться в диапазоне от 0 до 999999999.

По сравнению с sleep(3) и usleep(3), в nanosleep() есть следующие достоинства: он
позволяет задавать более точные интервалы времени, в POSIX.1 явно определено то,
что он не влияет на сигналы, и позволяет более лёгким способом возобновить паузу
после прерывания сигналом.



ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ


При удачной остановке на заданное время возвращаемое nanosleep() значение равно
нулю. Если вызов прерван обработчиком сигнала или произошла ошибка, то
возвращается -1, а переменной errno присваивается номер ошибки.



ОШИБКИ


EFAULT Проблема с копированием информации из пространства пользователя.

EINTR Пауза была прервана сигналом, отправленным нити (смотрите signal(7)).
Оставшееся время записано в *rem для того, чтобы нить могла вызвать
nanosleep() снова для возобновления паузы.

EINVAL Значение поля tv_nsec не находится в интервале от 0 до 999999999 или tv_sec
содержит отрицательное число.



СООТВЕТСТВИЕ СТАНДАРТАМ


POSIX.1-2001, POSIX.1-2008.



ЗАМЕЧАНИЯ


если использовать clock_nanosleep(2) с абсолютными величинами времени.

В POSIX.1 указано, что nanosleep() должен измерять время по часам CLOCK_REALTIME.
Однако, в Linux время измеряется с помощью часов CLOCK_MONOTONIC. Это, скорее
всего, не важно, так как в спецификации POSIX.1 для clock_settime(2) указано, что
быстро происходящие изменения в CLOCK_REALTIME не должны влиять на nanosleep():

Установка значения часов CLOCK_REALTIME с помощью clock_settime(2) не
оказывает влияния на нити, которые находятся в состоянии простоя из-за
служб, работа которых основана на этих часах, включая функцию nanosleep();
... В результате, интервал данных служб истечёт, когда истечёт запрошенный
относительный интервал, независимо от нового или старого значения часов.

Старое поведение
Для поддержки приложений, которым требуется указывать более точное время простоя
(например, чтобы управлять оборудованием, критичным к временным интервалам),
nanosleep() выдерживает время простоя до 2 мс с микросекундной точностью, если
вызывается из нити, запланированной выполняться в реальном времени с помощью
SCHED_FIFO или SCHED_RR. Это специальное расширение было удалено из ядра 2.5.39, и
поэтому недоступно в Linux версии 2.6.0 и более новых ядрах.



ДЕФЕКТЫ


Если программа, обрабатывающая сигналы и использующая nanosleep(), принимает
сигналы с очень высокой частотой, то возникают задержки планирования и ошибки
округления в ядерных подсчётах интервала сна и возвращается значение остатка, на
которое можно уверенно увеличивать интервал при последующем перезапуске вызова
nanosleep(). Чтобы избежать таких проблем используйте clock_nanosleep(2) с флагом
TIMER_ABSTIME, чтобы спать до абсолютного конечного срока.

В Linux 2.4, если nanosleep() останавливается по сигналу (например, SIGTSTP), то
после того, как нить продолжит работу по сигналу SIGCONT, вызов завершится
неудачно с ошибкой EINTR. Если системный вызов после этого перезапускается, то
время, которое нить провела в остановленном состоянии, не учитывается в интервале
остановки. Эта проблема исправлена в Linux 2.6.0 и новее.



СМОТРИТЕ ТАКЖЕ


clock_nanosleep(2), restart_syscall(2), sched_setscheduler(2), timer_create(2),
sleep(3), usleep(3), time(7)



Категория: (2) Системные вызовы ядра (функции языка Си) | Просмотров: 404 | Добавил: Администратор | Рейтинг: 0.0/0
Всего комментариев: 0
avatar