- bullseye-backports 4.17.0-2~bpo11+1
- testing 4.17.0-2
- unstable 4.17.0-2
GETITIMER(2) | Руководство программиста Linux | GETITIMER(2) |
ИМЯ¶
getitimer, setitimer - считывает или устанавливает значение таймера интервалов
СИНТАКСИС¶
#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);
ОПИСАНИЕ¶
Данные системные вызовы предоставляют доступ к интервальным таймерам, то есть таймерам, у которых изначально истекает срок в будущем, и (необязательно) с регулярными интервалами после. Когда у таймера истекает срок, вызвавшему процессу отправляется сигнал и таймер перезапускается с задаваемым интервалом (если интервал не равен нулю).
В аргументе which можно задать три типа таймеров, каждый выполняет отсчёт по разным часам и генерирует разный сигнал по истечении срока:
- ITIMER_REAL
- Этот таймер отсчитывается по реальному времени (то есть обычному). По каждому истечению выдаёт сигнал SIGALRM.
- ITIMER_VIRTUAL
- Этот таймер отсчитывается по времени ЦП в пользовательском режиме, проведённым процессом (учёт включает время ЦП, потреблённое всеми нитями процесса). По каждому истечению выдаёт сигнал SIGVTALRM.
- ITIMER_PROF
- Этот таймер отсчитывается по полному времени ЦП, потраченному процессом (учёт включает время ЦП, потреблённое всеми нитями процесса). По каждому истечению выдаёт сигнал SIGPROF.
- Данный таймер вместе с ITIMER_VIRTUAL можно использовать для профилирования затрат процессом системного и пользовательского времени ЦП.
Процесс может иметь только по одному таймеру каждого типа.
Величина, на которую устанавливается таймер, определяется следующими структурами:
struct itimerval {
struct timeval it_interval; /* интервал для периодического таймера */
struct timeval it_value; /* время до следующего окончания */ }; struct timeval {
time_t tv_sec; /* секунды */
suseconds_t tv_usec; /* микросекунды */ };
getitimer()¶
Функция getitimer() помещает текущее значение таймера, указанного в which, в буфер, указанный в curr_value.
Вложенная структура it_value содержит количество оставшегося времени до следующего истечения таймера. Это значение изменяется после начала отсчёта таймера и будет сброшено в it_interval при истечении таймера. Если оба поля it_value равны нулю, то это означает что таймер выключен (неактивен).
Вложенная структура it_interval содержит интервал таймера. Если оба поля it_intervalравны нулю, то это указывает на одноразовый таймер (то срабатывающий один раз).
setitimer()¶
Функция setitimer() настраивает таймер which значением new_value. Если значение old_value не NULL, то оно указывает на буфер, в который сохраняется предыдущее значение таймера (т. е., информация, возвращаемая getitimer()).
Если какое-то из полей в new_value.it_value не равно нулю, то таймер изначально включается как просроченный на указанное время. Если оба поля в new_value.it_value равны нулю, то таймер отключён.
Поле new_value.it_interval задаёт новый интервал таймера;если оба поля равны нулю, то таймер будет одноразовым.
ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ¶
При успешном выполнении возвращается 0. В случае ошибки возвращается -1, а errno устанавливается в соответствующее значение.
ОШИБКИ¶
СООТВЕТСТВИЕ СТАНДАРТАМ¶
POSIX.1-2001, SVr4, 4.4BSD (впервые этот вызов появился в 4.2BSD). В POSIX.1-2008 вызовы getitimer() и setitimer() помечены как устаревшие, и вместо них рекомендуется использовать программный интерфейс таймеров POSIX (timer_gettime(2), timer_settime(2) и т.д.).
ЗАМЕЧАНИЯ¶
Срок на таймерах никогда не заканчивается ранее указанного времени, но может (чуть-чуть) опоздать, что зависит от степени разрешения системного таймера и загрузки системы; смотрите time(7) (но смотрите ДЕФЕКТЫ далее). Если время таймера истекает во время работы процесса (всегда, если используется ITIMER_VIRTUAL), то сигнал после создания будет доставлен немедленно.
Потомок, созданный через 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.
СМ. ТАКЖЕ¶
gettimeofday(2), sigaction(2), signal(2), timer_create(2), timerfd_create(2), time(7)
ЗАМЕЧАНИЯ¶
Эта страница является частью проекта Linux man-pages версии 5.10. Описание проекта, информацию об ошибках и последнюю версию этой страницы можно найти по адресу https://www.kernel.org/doc/man-pages/.
ПЕРЕВОД¶
Русский перевод этой страницы руководства был сделан Azamat Hackimov <azamat.hackimov@gmail.com>, Dmitry Bolkhovskikh <d20052005@yandex.ru>, Vladislav <ivladislavefimov@gmail.com>, Yuri Kozlov <yuray@komyakino.ru> и Иван Павлов <pavia00@gmail.com>
Этот перевод является бесплатной документацией; прочитайте Стандартную общественную лицензию GNU версии 3 или более позднюю, чтобы узнать об условиях авторского права. Мы не несем НИКАКОЙ ОТВЕТСТВЕННОСТИ.
Если вы обнаружите ошибки в переводе этой страницы руководства, пожалуйста, отправьте электронное письмо на man-pages-ru-talks@lists.sourceforge.net.
11 апреля 2020 г. | Linux |