setitimer - считывает или устанавливает значение таймера
setitimer(2)
считывает или устанавливает значение таймера
Other Alias
getitimer
ОБЗОР
#include <sys/time.h>
int getitimer(int which, struct itimerval *curr_value);
int setitimer(int which, const struct itimerval *new_value,
struct itimerval *old_value);
ОПИСАНИЕ
Система предоставляет каждому процессу три таймера интервалов, значение
каждого из которых уменьшается на единицу по истечении установленного
времени. Когда у таймера истекает время, процессу отправляется сигнал и
таймер перезапускается с задаваемым интервалом (если не ноль).
ITIMER_REAL
уменьшается в режиме реального времени и выдаёт сигнал SIGALRM, когда
значение таймера становится равным 0.
ITIMER_VIRTUAL
уменьшается только во время работы процесса и выдаёт сигнал SIGVTALRM,
когда значение таймера становится равным 0.
ITIMER_PROF
уменьшается во время работы процесса и когда система выполняет что-либо по
заданию процесса. Этот таймер обычно используется вместе с ITIMER_VIRTUAL
для профилирования времени работы приложения в пользовательском режиме и
режиме ядра. Когда значение таймера становится равным 0, выдаётся сигнал
SIGPROF.
Величина, на которую устанавливается таймер, определяется следующими
структурами:
struct itimerval {
struct timeval it_interval; /* интервал для периодического таймера */
struct timeval it_value; /* время до следующего окончания */
};
struct timeval {
time_t tv_sec; /* секунды */
suseconds_t tv_usec; /* микросекунды */
};
Функция getitimer() заполняет структуру, указанную в curr_value,
текущим значением (т. е., количеством времени, оставшимся до следующего
истечения) таймера, указанное в which (может указываться: ITIMER_REAL,
ITIMER_VIRTUAL, ITIMER_PROF). В подполях структуры it_value
задаётся количество оставшегося времени таймера или ноль, если таймер
выключен. В поле it_interval задаётся интервал таймера (период); если в
этом поле возвращается значение ноль (в обоих подполях), то это указывает на
одноразовый таймер.
Функция setitimer() настраивает указанный таймер значением
new_value. Если значение old_value не NULL, то в него сохраняется
старое значение таймера (т. е., информация, возвращаемая getitimer()).
Значения таймеров уменьшаются от величины it_value до нуля, выдаётся
сигнал, и значения вновь устанавливаются равными it_interval. Таймер,
установленный на ноль (его величина it_value равна нулю, или время вышло
и величина it_interval равна нулю), останавливается.
Величины tv_sec и tv_usec являются основными при установке таймера.
Срок на таймерах никогда не заканчивается ранее указанного времени, но может
(чуть-чуть) опоздать, что зависит от степени разрешения системного таймера и
загрузки системы; смотрите time(7) (но смотрите ДЕФЕКТЫ далее). По
истечении времени будет послан сигнал, а таймер обнулится. Если время
таймера истекает во время работы процесса (всегда, если используется
ITIMER_VIRTUAL), то сигнал после создания будет доставлен
немедленно. Иначе отсылка сигнала откладывается на небольшой промежуток
времени, зависящий от степени загруженности системы.
ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При успешном выполнении возвращается 0. В случае ошибки возвращается -1, а
errno устанавливается в соответствующее значение.
ОШИБКИ
EFAULT
Указатели new_value, old_value или curr_value являются
некорректными.
EINVAL
Значение which не равно ITIMER_REAL, ITIMER_VIRTUAL или
ITIMER_PROF; или (начиная с Linux 2.6.22) одно из полей структуры
tv_usec, указанной в new_value, содержит значение вне диапазона от 0
до 999999.
СООТВЕТСТВИЕ СТАНДАРТАМ
POSIX.1-2001, SVr4, 4.4BSD (впервые этот вызов появился в 4.2BSD). В
POSIX.1-2008 вызовы
getitimer() и
setitimer() помечены как устаревшие,
и вместо них рекомендуется использовать программный интерфейс таймеров POSIX
(
timer_gettime(2),
timer_settime(2) и т.д.).
ЗАМЕЧАНИЯ
Потомок, созданный через
fork(2), не наследует таймеры интервалов
родителя. При вызове
execve(2) таймеры интервалов сохраняются.
В POSIX.1 не определено взаимодействие между setitimer() и тремя
интерфейсами: alarm(2), sleep(3) и usleep(3).
В стандартах ничего не говорится о значении вызова:
setitimer(which, NULL, &old_value);
В многих системах (Solaris, BSD и, возможно, другие) он считается
эквивалентом:
getitimer(which, &old_value);
В Linux это эквивалентно вызову, в котором поля new_value равны 0, то
есть таймер выключен. Не используйте это особенность Linux: это
непереносимо и нецелесообразно.
ДЕФЕКТЫ
Генерирование и доставка сигнала разделены, и только один экземпляр каждого
сигнала, которые описаны выше, может ожидать передачи в процесс. При очень
большой нагрузке, ожидание таймера
ITIMER_REAL может завершиться раньше
чем будет доставлен сигнал о предыдущем завершении. Второй сигнал об этом
событии будет потерян.
В ядрах Linux до версии 2.6.16, значения таймеров указывались в мигах. Если
запрашивалась установка таймера в значение, представление в мигах которого
превышало MAX_SEC_IN_JIFFIES (определено в include/linux/jiffies.h),
то значение таймера просто урезалось до этого максимального значения. На
Linux/i386 (где, начиная с Linux 2.6.13, по умолчанию миг равен 0.004
секунды), это означало, что максимальное значение таймера приблизительно
равнялось 99.42 дня. Начиная с Linux 2.6.16, в ядрах стали использовать
другое внутреннее представление времени, и этот предел был снят.
В некоторых системах (включая i386), ядра Linux до версии 2.6.12 содержали
дефект, который при определённых условиях приводил к преждевременному
завершению за один миг (jiffy). Этот дефект исправлен в ядре 2.6.12.
В POSIX.1-2001 сказано, что setitimer() должен завершаться с ошибкой,
если значение tv_usec лежит вне диапазона от 0 до 999999. Однако, в ядрах
до версии 2.6.21 включительно, в Linux ошибка не выдаётся, а вместо этого
значение таймера просто подгоняется под соответствующие секунды. Начиная с
ядра 2.6.22, это несоответствие убрано: некорректное значение tv_usec
приводит к ошибке EINVAL.