.\" -*- coding: UTF-8 -*- .\" Copyright (C) 2008 Michael Kerrisk .\" .\" SPDX-License-Identifier: GPL-2.0-or-later .\" .\"******************************************************************* .\" .\" This file was generated with po4a. Translate the source file. .\" .\"******************************************************************* .TH timerfd_create 2 "3 мая 2023 г." "Linux man\-pages 6.05.01" .SH ИМЯ timerfd_create, timerfd_settime, timerfd_gettime \- таймеры, уведомляющие через файловые дескрипторы .SH LIBRARY Standard C library (\fIlibc\fP, \fI\-lc\fP) .SH СИНТАКСИС .nf \fB#include \fP .PP \fBint timerfd_create(int \fP\fIclockid\fP\fB, int \fP\fIflags\fP\fB);\fP .PP \fBint timerfd_settime(int \fP\fIfd\fP\fB, int \fP\fIflags\fP\fB,\fP \fB const struct itimerspec *\fP\fInew_value\fP\fB,\fP \fB struct itimerspec *_Nullable \fP\fIold_value\fP\fB);\fP \fBint timerfd_gettime(int \fP\fIfd\fP\fB, struct itimerspec *\fP\fIcurr_value\fP\fB);\fP .fi .SH ОПИСАНИЕ Эти системные вызовы создают и работают с таймером, доставляя уведомления о срабатывании через файловый дескриптор. Они предоставляют альтернативу \fBsetitimer\fP(2) или \fBtimer_create\fP(2); их преимущество в том, что за файловым дескриптором можно следить с помощью \fBselect\fP(2), \fBpoll\fP(2) и \fBepoll\fP(7). .PP .\" Использование данных трёх системных вызовов аналогично \fBtimer_create\fP(2), \fBtimer_settime\fP(2) и \fBtimer_gettime\fP(2) (аналога \fBtimer_getoverrun\fP(2) нет, так как его возможности предоставляет \fBread\fP(2) как описано ниже). .SS timerfd_create() Вызов \fBtimerfd_create\fP() создаёт новый объект таймера и возвращает файловый дескриптор, который ссылается на этот таймер. В аргументе \fIclockid\fP задаются часы, которые используются для хода таймера; значением должно быть одно из следующих: .TP \fBCLOCK_REALTIME\fP Настраиваемые системные часы реального времени. .TP \fBCLOCK_MONOTONIC\fP Ненастраиваемые, постоянно идущие вперёд часы, отсчитывающие время с некоторой неопределённой точки в прошлом, которая не изменяется с момент запуска системы. .TP \fBCLOCK_BOOTTIME\fP (начиная с Linux 3.15) .\" commit 4a2378a943f09907fb1ae35c15de917f60289c14 Подобно \fBCLOCK_MONOTONIC\fP, представляет монотонно растущие часы. Однако, если часы \fBCLOCK_MONOTONIC\fP не отсчитывают время когда система находится в состоянии ожидания (suspended), а часы \fBCLOCK_BOOTTIME\fP учитывают время в таком состоянии системы. Это полезно приложениям, которым необходимо учитывать состояние ожидания. \fBCLOCK_REALTIME\fP не подходят для таких приложений, так как эти часы подвержены скачкообразным изменениям системных часов. .TP \fBCLOCK_REALTIME_ALARM\fP (начиная с Linux 3.11) .\" commit 11ffa9d6065f344a9bd769a2452f26f2f671e5f8 Эти часы подобны \fBCLOCK_REALTIME\fP, но разбудят систему, если она находится с состоянии ожидания. Для установки таймера по этим часам вызывающий должен иметь мандат \fBCAP_WAKE_ALARM\fP. .TP \fBCLOCK_BOOTTIME_ALARM\fP (начиная с Linux 3.11) .\" commit 11ffa9d6065f344a9bd769a2452f26f2f671e5f8 Эти часы подобны \fBCLOCK_BOOTTIME\fP, но разбудят систему, если она находится с состоянии ожидания. Для установки таймера по этим часам вызывающий должен иметь мандат \fBCAP_WAKE_ALARM\fP. .PP See \fBclock_getres\fP(2) for some further details on the above clocks. .PP Текущее значение каждого из этих часов можно получить с помощью \fBclock_gettime\fP(2). .PP Начиная с Linux 2.6.27, для изменения поведения \fBtimerfd_create\fP() можно использовать следующие значения \fIflags\fP (через OR): .TP 14 \fBTFD_NONBLOCK\fP Устанавливает флаг состояния файла \fBO_NONBLOCK\fP для нового открытого файлового описания (смотрите \fBopen\fP(2)), на которое ссылается новый файловый дескриптор. Использование данного флага делает ненужными дополнительные вызовы \fBfcntl\fP(2) для достижения того же результата. .TP \fBTFD_CLOEXEC\fP Устанавливает флаг close\-on\-exec (\fBFD_CLOEXEC\fP) для нового открытого файлового дескриптора. Смотрите описание флага \fBO_CLOEXEC\fP в \fBopen\fP(2) для того, чтобы узнать как это может пригодиться. .PP До Linux 2.6.26 включительно аргумент \fIflags\fP должен быть равен нулю. .SS timerfd_settime() Вызов \fBtimerfd_settime\fP() запускает или останавливает таймер, на который ссылается файловый дескриптор \fIfd\fP. .PP The \fInew_value\fP argument specifies the initial expiration and interval for the timer. The \fIitimerspec\fP structure used for this argument is described in \fBitimerspec\fP(3type). .PP В \fInew_value.it_value\fP задаётся первое срабатывание таймера, в секундах и наносекундах. Установка любого из полей \fInew_value.it_value\fP в ненулевое значение включает таймер. Установка обоих полей \fInew_value.it_value\fP в ноль выключает таймер. .PP Установка одного или обоих полей \fInew_value.it_interval\fP в ненулевое значение задаёт период, в секундах и наносекундах, периодического срабатывания таймера после первого срабатывания. Если оба поля \fInew_value.it_interval\fP равны нулю, то таймер срабатывает только один раз, во время, указанное в \fInew_value.it_value\fP. .PP По умолчанию, начальное время срабатывания, задаваемое в \fInew_value\fP, считается относительно текущего времени часов таймера на момент вызова (т. е., в \fInew_value.it_value\fP задаётся время относительно текущего значения часов, заданных в \fIclockid\fP). Использование абсолютной задержки можно включить через аргумент \fIflags\fP. .PP Аргумент \fIflags\fP является битовой маской, которая может включать следующие значения: .TP \fBTFD_TIMER_ABSTIME\fP Считать \fInew_value.it_value\fP абсолютным значением часов таймера. Таймер сработает, когда значение часов таймера достигнет значения, указанного в \fInew_value.it_value\fP. .TP \fBTFD_TIMER_CANCEL_ON_SET\fP Если этот флаг указан вместе с \fBTFD_TIMER_ABSTIME\fP и часами этого таймера являются \fBCLOCK_REALTIME\fP или \fBCLOCK_REALTIME_ALARM\fP, то помечать этот таймер как отменяемый, если часы реального времени подвергнуться скачкообразному изменению (\fBsettimeofday\fP(2), \fBclock_settime\fP(2) или подобными). Когда такие изменения происходят, текущий или будущий вызова \fBread\fP(2) для файлового дескриптора завершается с ошибкой \fBECANCELED\fP. .PP .\" Если \fIold_value\fP не равно NULL, то это указатель на структуру \fIitimerspec\fP, и он будет использоваться для возврата текущих на момент вызова настроек таймера; смотрите описание \fBtimerfd_gettime\fP() далее. .SS timerfd_gettime() Вызов \fBtimerfd_gettime\fP() возвращает в \fIcurr_value\fP, которое указывает на структуру \fIitimerspec\fP, текущие настройки таймера, на который ссылается файловый дескриптор \fIfd\fP. .PP В поле \fIit_value\fP возвращается время до следующего срабатывания таймера. Если оба поля этой структуры равны нулю, то таймер в данный момент не запущен. Это поле всегда содержит относительное значение, независимо от того, был ли указан флаг \fBTFD_TIMER_ABSTIME\fP при настройке таймера. .PP В поле \fIit_interval\fP возвращается интервал таймера. Если оба поля этой структуры равны нулю, то таймер настроен на однократное срабатывание, на время, заданное в \fIcurr_value.it_value\fP. .SS "Работа с файловым дескриптором таймера" The file descriptor returned by \fBtimerfd_create\fP() supports the following additional operations: .TP \fBread\fP(2) If the timer has already expired one or more times since its settings were last modified using \fBtimerfd_settime\fP(), or since the last successful \fBread\fP(2), then the buffer given to \fBread\fP(2) returns an unsigned 8\-byte integer (\fIuint64_t\fP) containing the number of expirations that have occurred. (The returned value is in host byte order\[em]that is, the native byte order for integers on the host machine.) .IP Если таймер ещё не срабатывал до вызова \fBread\fP(2), то вызов блокирует выполнение до следующего срабатывания таймера, или завершается с ошибкой \fBEAGAIN\fP, если файловый дескриптор был создан неблокирующим (с помощью вызова \fBfcntl\fP(2) и операции \fBF_SETFL\fP с флагом \fBO_NONBLOCK\fP). .IP Вызов \fBread\fP(2) завершается ошибкой \fBEINVAL\fP, если размер указанного буфера будет меньше 8 байт. .IP Если используются часы \fBCLOCK_REALTIME\fP или \fBCLOCK_REALTIME_ALARM\fP, таймер является абсолютным (\fBTFD_TIMER_ABSTIME\fP) и при вызове \fBtimerfd_settime\fP() указан флаг \fBTFD_TIMER_CANCEL_ON_SET\fP, то \fBread\fP(2) завершается ошибкой \fBECANCELED\fP, если часы реального времени подвергнуться скачкообразному изменению (это позволяет читающему приложению обнаружить такие скачкообразные изменения часов). .IP If the associated clock is either \fBCLOCK_REALTIME\fP or \fBCLOCK_REALTIME_ALARM\fP, the timer is absolute (\fBTFD_TIMER_ABSTIME\fP), and the flag \fBTFD_TIMER_CANCEL_ON_SET\fP was \fInot\fP specified when calling \fBtimerfd_settime\fP(), then a discontinuous negative change to the clock (e.g., \fBclock_settime\fP(2)) may cause \fBread\fP(2) to unblock, but return a value of 0 (i.e., no bytes read), if the clock change occurs after the time expired, but before the \fBread\fP(2) on the file descriptor. .TP \fBpoll\fP(2), \fBselect\fP(2) (и подобные) Файловый дескриптор доступен для чтения (в \fBselect\fP(2) аргумент \fIreadfds\fP; в \fBpoll\fP(2) флаг \fBPOLLIN\fP), если произошло одно или более срабатываний таймера. .IP Файловый дескриптор также поддерживает другие мультиплексные вызовы: \fBpselect\fP(2), \fBppoll\fP(2) и \fBepoll\fP(7). .TP \fBioctl\fP(2) Поддерживается следующая команда, относящаяся к timerfd: .RS .TP \fBTFD_IOC_SET_TICKS\fP (начиная с Linux 3.17) .\" commit 5442e9fbd7c23172a1c9bc736629cd123a9923f0 Корректирует количество истечений таймера, которые произошли. Аргументом является указатель на ненулевое 8\-байтовое целое (\fIuint64_t\fP*), содержащее новое количество истечений. После установки количества, все ожидающие таймера пробуждаются. Единственная цель данной команды — восстановить истечений для отсечки/восстановления. Данная операция доступна только, если ядро собрано с параметром \fBCONFIG_CHECKPOINT_RESTORE\fP. .RE .TP \fBclose\fP(2) .\" Если файловый дескриптор больше не требуется, его нужно закрыть. Когда все файловые дескрипторы, связанные с одним объектом таймера, будут закрыты, таймер выключается и ядро освобождает его ресурсы. .SS "Поведение при fork(2)" .\" После \fBfork\fP(2) потомки наследуют копию файлового дескриптора, созданного \fBtimerfd_create\fP(). Файловый дескриптор потомка ссылается на тот же объект таймера, что и файловый дескриптор его родителя, и операция \fBread\fP(2) в потомке будет возвращать информацию о срабатываниях таймера. .SS "Поведение при execve(2)" Файловый дескриптор, созданный \fBtimerfd_create\fP(), сохраняется при \fBexecve\fP(2), и продолжает генерировать срабатывания таймера, если он включён. .SH "ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ" При успешном выполнении \fBtimerfd_create\fP() возвращает новый файловый дескриптор. При ошибке возвращается \-1, и \fIerrno\fP устанавливается в соответствующее значение. .PP При успешном выполнении \fBtimerfd_settime\fP() и \fBtimerfd_gettime\fP() возвращают 0; в случае ошибки возвращается \-1, а \fIerrno\fP устанавливается в соответствующее значение ошибки. .SH ОШИБКИ Вызов \fBtimerfd_create\fP() может завершиться со следующими ошибками: .TP \fBEINVAL\fP The \fIclockid\fP is not valid. .TP \fBEINVAL\fP Неправильное значение \fIflags\fP или, для Linux 2.6.26 и старее, \fIflags\fP не равно 0. .TP \fBEMFILE\fP Было достигнуто ограничение по количеству открытых файловых дескрипторов на процесс. .TP \fBENFILE\fP Достигнуто максимальное количество открытых файлов в системе. .TP \fBENODEV\fP Не удалось смонтировать (внутреннее) безымянное устройство inode. .TP \fBENOMEM\fP Недостаточно памяти ядра для создания таймера. .TP \fBEPERM\fP \fIclockid\fP was \fBCLOCK_REALTIME_ALARM\fP or \fBCLOCK_BOOTTIME_ALARM\fP but the caller did not have the \fBCAP_WAKE_ALARM\fP capability. .PP Вызовы \fBtimerfd_settime\fP() и \fBtimerfd_gettime\fP() могут завершаться со следующими ошибками: .TP \fBEBADF\fP Значение \fIfd\fP не является правильным файловым дескриптором. .TP \fBEFAULT\fP Некорректный указатель \fInew_value\fP, \fIold_value\fP или \fIcurr_value\fP. .TP \fBEINVAL\fP Значение \fIfd\fP не является правильным файловым дескриптором timerfd. .PP Вызов \fBtimerfd_settime\fP() также может завершиться со следующими ошибками: .TP \fBECANCELED\fP Смотрите ЗАМЕЧАНИЯ. .TP \fBEINVAL\fP Значение \fInew_value\fP некорректно инициализировано (одно из \fItv_nsec\fP вне диапазона от 0 до 999999999). .TP \fBEINVAL\fP .\" This case only checked since Linux 2.6.29, and Linux 2.2.2[78].some-stable-version. .\" In older kernel versions, no check was made for invalid flags. Значение \fIflags\fP неверно. .SH СТАНДАРТЫ Linux. .SH ИСТОРИЯ Linux 2.6.25, glibc 2.8. .SH ЗАМЕЧАНИЯ Suppose the following scenario for \fBCLOCK_REALTIME\fP or \fBCLOCK_REALTIME_ALARM\fP timer that was created with \fBtimerfd_create\fP(): .IP (1) 5 The timer has been started (\fBtimerfd_settime\fP()) with the \fBTFD_TIMER_ABSTIME\fP and \fBTFD_TIMER_CANCEL_ON_SET\fP flags; .IP (2) A discontinuous change (e.g., \fBsettimeofday\fP(2)) is subsequently made to the \fBCLOCK_REALTIME\fP clock; and .IP (3) the caller once more calls \fBtimerfd_settime\fP() to rearm the timer (without first doing a \fBread\fP(2) on the file descriptor). .PP In this case the following occurs: .IP \[bu] 3 The \fBtimerfd_settime\fP() returns \-1 with \fIerrno\fP set to \fBECANCELED\fP. (This enables the caller to know that the previous timer was affected by a discontinuous change to the clock.) .IP \[bu] The timer \fIis successfully rearmed\fP with the settings provided in the second \fBtimerfd_settime\fP() call. (This was probably an implementation accident, but won't be fixed now, in case there are applications that depend on this behaviour.) .SH ДЕФЕКТЫ .\" 2.6.29 В настоящее время \fBtimerfd_create\fP() поддерживает только несколько типов идентификаторов часов, поддерживаемых \fBtimer_create\fP(2). .SH ПРИМЕРЫ Следующая программа создаёт таймер и затем следит за его работой. Программа получает до трёх аргументов из командной строки. В первом аргументе задаётся количество секунд до первого срабатывания таймера. Во втором аргументе задаётся интервал таймера в секундах. В третьем аргументе задаётся сколько программа должна позволить сработать таймеру до завершения. Второй и третий аргументы необязательны. .PP Следующий сеанс работы в оболочке показывает работу с программой: .PP .in +4n .EX $\fB a.out 3 1 100\fP 0.000: timer started 3.000: read: 1; total=1 4.000: read: 1; total=2 \fB\[ha]Z \fP # type control\-Z to suspend the program [1]+ Stopped ./timerfd3_demo 3 1 100 $ \fBfg\fP # Resume execution after a few seconds a.out 3 1 100 9.660: read: 5; total=7 10.000: read: 1; total=8 11.000: read: 1; total=9 \fB\[ha]C \fP # type control\-C to suspend the program .EE .in .SS "Исходный код программы" .\" SRC BEGIN (timerfd_create.c) \& .EX .\" The commented out code here is what we currently need until .\" the required stuff is in glibc .\" .\" .\"/* Link with \-lrt */ .\"#define _GNU_SOURCE .\"#include .\"#include .\"#include .\"#if defined(__i386__) .\"#define __NR_timerfd_create 322 .\"#define __NR_timerfd_settime 325 .\"#define __NR_timerfd_gettime 326 .\"#endif .\" .\"static int .\"timerfd_create(int clockid, int flags) .\"{ .\" return syscall(__NR_timerfd_create, clockid, flags); .\"} .\" .\"static int .\"timerfd_settime(int fd, int flags, struct itimerspec *new_value, .\" struct itimerspec *curr_value) .\"{ .\" return syscall(__NR_timerfd_settime, fd, flags, new_value, .\" curr_value); .\"} .\" .\"static int .\"timerfd_gettime(int fd, struct itimerspec *curr_value) .\"{ .\" return syscall(__NR_timerfd_gettime, fd, curr_value); .\"} .\" .\"#define TFD_TIMER_ABSTIME (1 << 0) .\" .\"//////////////////////////////////////////////////////////// #include #include #include #include #include #include #include \& static void print_elapsed_time(void) { int secs, nsecs; static int first_call = 1; struct timespec curr; static struct timespec start; \& if (first_call) { first_call = 0; if (clock_gettime(CLOCK_MONOTONIC, &start) == \-1) err(EXIT_FAILURE, "clock_gettime"); } \& if (clock_gettime(CLOCK_MONOTONIC, &curr) == \-1) err(EXIT_FAILURE, "clock_gettime"); \& secs = curr.tv_sec \- start.tv_sec; nsecs = curr.tv_nsec \- start.tv_nsec; if (nsecs < 0) { secs\-\-; nsecs += 1000000000; } printf("%d.%03d: ", secs, (nsecs + 500000) / 1000000); } \& int main(int argc, char *argv[]) { int fd; ssize_t s; uint64_t exp, tot_exp, max_exp; struct timespec now; struct itimerspec new_value; \& if (argc != 2 && argc != 4) { fprintf(stderr, "%s init\-secs [interval\-secs max\-exp]\en", argv[0]); exit(EXIT_FAILURE); } \& if (clock_gettime(CLOCK_REALTIME, &now) == \-1) err(EXIT_FAILURE, "clock_gettime"); \& /* Create a CLOCK_REALTIME absolute timer with initial expiration and interval as specified in command line. */ \& new_value.it_value.tv_sec = now.tv_sec + atoi(argv[1]); new_value.it_value.tv_nsec = now.tv_nsec; if (argc == 2) { new_value.it_interval.tv_sec = 0; max_exp = 1; } else { new_value.it_interval.tv_sec = atoi(argv[2]); max_exp = atoi(argv[3]); } new_value.it_interval.tv_nsec = 0; \& fd = timerfd_create(CLOCK_REALTIME, 0); if (fd == \-1) err(EXIT_FAILURE, "timerfd_create"); \& if (timerfd_settime(fd, TFD_TIMER_ABSTIME, &new_value, NULL) == \-1) err(EXIT_FAILURE, "timerfd_settime"); \& print_elapsed_time(); printf("timer started\en"); \& for (tot_exp = 0; tot_exp < max_exp;) { s = read(fd, &exp, sizeof(uint64_t)); if (s != sizeof(uint64_t)) err(EXIT_FAILURE, "read"); \& tot_exp += exp; print_elapsed_time(); printf("read: %" PRIu64 "; total=%" PRIu64 "\en", exp, tot_exp); } \& exit(EXIT_SUCCESS); } .EE .\" SRC END .SH "СМ. ТАКЖЕ" \fBeventfd\fP(2), \fBpoll\fP(2), \fBread\fP(2), \fBselect\fP(2), \fBsetitimer\fP(2), \fBsignalfd\fP(2), \fBtimer_create\fP(2), \fBtimer_gettime\fP(2), \fBtimer_settime\fP(2), \fBtimespec\fP(3), \fBepoll\fP(7), \fBtime\fP(7) .PP .SH ПЕРЕВОД Русский перевод этой страницы руководства был сделан Azamat Hackimov , Dmitry Bolkhovskikh , Yuri Kozlov и Иван Павлов . .PP Этот перевод является бесплатной документацией; прочитайте .UR https://www.gnu.org/licenses/gpl-3.0.html Стандартную общественную лицензию GNU версии 3 .UE или более позднюю, чтобы узнать об условиях авторского права. Мы не несем НИКАКОЙ ОТВЕТСТВЕННОСТИ. .PP Если вы обнаружите ошибки в переводе этой страницы руководства, пожалуйста, отправьте электронное письмо на .MT man-pages-ru-talks@lists.sourceforge.net .ME .