Scroll to navigation

timerfd_create(2) System Calls Manual timerfd_create(2)

NAVN

timerfd_create, timerfd_settime, timerfd_gettime - stopure der påminder via fildeskriptorer

BIBLIOTEK

Standard C library (libc-lc)

SYNOPSIS

#include <sys/timerfd.h>
int timerfd_create(int clockid, int flag);
int timerfd_settime(int fd, int flag,
                    const struct itimerspec *ny_værdi,
                    struct itimerspec *_Nullable gl_værdi);
int timerfd_gettime(int fd, struct itimerspec *nuv_værdi);

BESKRIVELSE

Disse systemkald opretter og fungerer på et stopur, der leverer påmindelser om udløb for stopure via en fildeskriptor. De tilbyder et alternativ til brugen af setitimer(2) eller timer_create(2), med den fordel at fildeskriptoren kan overvåges af select(2), poll(2) og epoll(7).

Brugen af disse tre systemkald er analog til brugen af timer_create(2), timer_settime(2) og timer_gettime(2). (Der er ingen analog for timer_getoverrun(2) da den funktionalitet tilbydes af read(2), som beskrevet nedenfor).

timerfd_create()

timerfd_create() opretter et nyt stopurobjekt og returnerer en fildeskriptor, der referer til det stopur. Argumentet clockid angiver uret, der bruges til at markere status for stopuret, og skal være en af de følgende:

Et realtids ur, der kan angives for hele systemet.
Et monotont stigende ur, der ikke kan indstilles og som måler tid fra et uangivet punkt i fortiden, der ikke ændrer sig efter systemets opstartstidspunkt.
Som CLOCK_MONOTONIC, er dette et monotont stigende ur. Hvor CLOCK_MONOTONIC ikke måler tiden mens et system er i dvale, så inkluderer CLOCK_BOOTTIME tiden hvor systemet er i dvale. Dette er nyttigt for programmer, der skal være dvale-opmærksomme. CLOCK_REALTIME er ikke egnet for sådanne programmer, da uret påvirkes af diskontinuerlige ændringer til systemuret.
Dette ur er som CLOCK_REALTIME, men vil vække systemet, hvis det er i dvale. Kalderen skal have funktionaliteten CAP_WAKE_ALARM for at angive et stopur mod dette ur.
Dette ur er som CLOCK_BOOTTIME, men vil vække systemet, hvis det er i dvale. Kalderen skal have funktionaliteten CAP_WAKE_ALARM for at kunne angive et stopur mod dette ur.

Se clock_getres(2) for yderligere detaljer om ovenstående ure.

Den nuværende værdi af hver af disse ure kan indhentes via clock_gettime(2).

Startende med Linux 2.6.27 kan de følgende værdier blive bit-vis ORed i flag for at ændre opførelsen for timerfd_create():

Angiv filstatusflaget O_NONBLOCK på den åbne filbeskrivelse (se open(2)) refereret til af den nye fildeskriptor. Brug af dette flag forhindrer ekstra kald til fcntl(2) for at opnå det samme resultat.
Angiv flaget close-on-exec (FD_CLOEXEC) på den nye fildeskriptor. Se beskrivelsen af flaget O_CLOEXEC i open(2) for årsagerne til hvorfor dette kan være nyttigt.

I Linuxversioner op til og inklusive 2.6.26 skal flag være angivet som nul.

timerfd_settime()

timerfd_settime() bevæbner (starter) eller afvæbner (stopper) stopuret refereret til af fildeskriptoren fd.

Arguementet ny_værdi angiver det oprindelige udløb og interval for stopuret. Strukturen itimerspec brugt for dette argument er beskrevet i itimerspec(3type).

new_value.it_value angiver det oprindelige udløb for stopuret, i sekunder og nanosekunder. Angivelse af et af felterne i new_value.it_value til en værdi anderledes end nul bevæbner stopuret. Angivelse af begge felter i new_value.it_value til nul afvæbner stopuret.

Angivelse af et eller begge felter i new_value.it_interval til værdier forskellige fra nul angiver perioden, i sekunder og nanosekunder, for gentagne stopursudløb efter det oprindelige udløb. Hvis begge felter i new_value.it_interval er nul, så udløber stopuret bare en gang, på tidspunktet angivet af new_value.it_value.

Som standard fortolkes den oprindelige udløbstid angivet i ny_værdi relativ til den nuværende tid på stopurets ur på tidspunktet for kaldet (dvs. new_value.it_value angiver en tid relativ til den nuværende værdi for uret angivet af clockid). Et absolut tidsudløb kan vælges via argumentet flag.

Argumentet flag er en bit-maske, der kan inkludere de følgende værdier:

Fortolk new_value.it_value som en absolut værdi på stopurets ur. Stopuret vil udløbe når værdien af stopurets ur når værdien angivet i new_value.it_value.
Hvis dette flag er angivet med TFD_TIMER_ABSTIME og uret for dette stopur er CLOCK_REALTIME eller CLOCK_REALTIME_ALARM, så marker dette stopur som om det kan afbestilles hvis realtidsuret har en diskontinuerlig ændring (settimeofday(2), clock_settime(2) eller lignende). Når sådanne ændringer opstår vil en nuværende eller fremtidig read(2) fra fildeskriptoren fejle med fejlbeskeden ECANCELED.

Hvis argumentet gl_værdi ikke er NULL, så bruges strukturen itimerspec der peges på til at returnere indstillingen for stopuret, der var gyldig på tidspunktet for kaldet; se beskrivelsen af timerfd_gettime() der følger.

timerfd_gettime()

timerfd_gettime() returnerer, i nuv_værdi, en itimerspec-struktur der indheolder den nuværende indstilling for stopuret refereret til af fildeskriptoren fd.

Feltet it_value returnerer tidsintervallet indtil stopuret næste gang udløber. Hvis begge felter for denne struktur er nul, så er stopuret afvæbnet. Dette felt indeholder en relativ værdi, uanset om flaget TFD_TIMER_ABSTIME var angivet da stopuret blev indstillet.

Feltet it_interval returnerer intervallet for stopuret. Hvis begge felter for denne struktur er nul, så er stopuret sat til at udløb bare en gang, på tidspunktet angivet af curr_value.it_value.

Operationer på et stopurs fildeskriptor

Fildeskriptoren returneres af timerfd_create() understøtter de følgende yderligere operationer:

read(2)
Hvis stopuret allerede er udløbet en eller flere gange siden dets indstillinger sidst blev ændret via timerfd_settime(), eller siden den sidste succesfulde read(2), så returnerer mellemlageret angivet til read(2) et ej underskrevet 8-byte heltal (uint64_t) indeholdende antallet af udløb, der er opstået. (Den returnerede værdi er i vært-byterækkefølge—det vil sige, byte-standardrækkefølgen for heltal på værtsmaskinen).
Hvis intet stopurudløb er sket på tidspunktet for read(2), så blokerer kaldet enten det næste stopursudløb eller fejler med den følgende fejlbesked EAGAIN hvis fildeskriptoren er gjort ikkeblokerende (via brugen af fcntl(2) F_SETFL-operationen til at angive flaget O_NONBLOCK).
En read(2) fejler med fejlbeskeden EINVAL hvis størrelsen for det angivne mellemlager er mindre end 8 byte.
Hvis det associerede ur er enten CLOCK_REALTIME eller CLOCK_REALTIME_ALARM, er stopuret absolut (TFD_TIMER_ABSTIME) og flaget TFD_TIMER_CANCEL_ON_SET var angivet da timerfd_settime() blev kaldet, så fejler read(2) med fejlbeskeden ECANCELED hvis realtidsuret har en diskontinuerlig ændring. (Dette gør det muligt for det læsende program at registrere sådanne diskontinuerlige ændringer til uret).
Hvis det associerede ur er enten CLOCK_REALTIME eller CLOCK_REALTIME_ALARM, er stopuret absolut (TFD_TIMER_ABSTIME) og flaget TFD_TIMER_CANCEL_ON_SET ikke var angivet da timerfd_settime() blev kaldt, så kan en diskontinuerlig negativ ændring til uret (f.eks. clock_settime(2)) få read(2) til at fjerne blokering, men returnere en værdi på 0 (dvs. ingen byte læst), hvis ur-ændringen opstår efter tiden udløb, men før read(2) på fildeskriptoren.
poll(2)
select(2)
(og lignende)
Fildeskriptoren kan læses (argumentet select(2) readfds; flaget poll(2) POLLIN) hvis en ellere flere stopursudløb er opstået.
Fildeskriptoren understøtter også de andre fil-deskriptor multiplexing-API'er: pselect(2), ppoll(2) og epoll(7).
ioctl(2)
Den følgende timerfd-specifikke kommando er understøttet:
Juster antallet af stopursudløb der er opstået. Argumentet er en peger til et 8-byte heltal forskellige fra nul (uint64_t*) indeholdende det nye antal udløb. Når antallet er angivet, vil en eventuel tjener på stopuret blive vækket. Det eneste formål med denne kommando er at gendanne udløbene til tjekpunkt/gendannelse. Denne operation er kun tilgængelig hvis kernen blev konfigureret med tilvalget CONFIG_CHECKPOINT_RESTORE.
close(2)
Når fildeskriptoren ikke længere er krævet, så bør den lukkes. Når alle fildeskriptorer associeret med det samme stopursobjekt er blevet lukket, så afvæbnes stopuret og dets ressurcer frigives af kernen.

fork(2)-semantik

Efter en fork(2) arver underprocessen en kopi af fildeskriptoren oprettet af timerfd_create(). Fildeskriptoren refererer til det samme underliggende stopursobjekt som den tilsvarende fildeskriptor i overprocessen, og read(2)'er i underprocessen vil returnere information om udløb for stopuret.

execve(2)-semantik

En fildeskriptor oprettet af timerfd_create() bevares på tværs af execve(2), og fortsætter med at oprette stopursudløb hvis stopuret var bevæbnet.

RETURVÆRDI

Ved succes, returnerer timerfd_create() en ny fildeskriptor. Ved fejl, returneres -1 og errno angives for at indikere fejlen.

timerfd_settime() og timerfd_gettime() returnerer 0 ved succes; ved fejl returnerer de -1, og angiver errno for at indikere fejlen.

FEJL

timerfd_create() kan fejle med de følgende fejlbeskeder:

clockid er ikke gyldig.
flag er ugyldig; eller, i Linux 2.6.26 eller tidligere, flag er forskellig fra nul.
Begrænsningen per proces for antallet af åbne fildeskriptorer er blevet nået.
Systemets begrænsning på det samlede antal åbne filer er nået.
Kunne ikke montere (intern) anonym iknude-enhed.
Der var utilstrækkelige kernehukommelse til at oprette stopuret.
clockid var CLOCK_REALTIME_ALARM eller CLOCK_BOOTTIME_ALARM men kalderen havde ikke funktionaliteten CAP_WAKE_ALARM.

timerfd_settime() og timerfd_gettime() kan fejle med de følgende fejl:

fd er ikke en gyldig filbeskrivelse.
ny_værdi, gl_værdi eller nuv_værdi er ikke en gyldig peger.
fd er ikke en gyldig timerfd-fildeskriptor.

timerfd_settime() kan også fejl med de følgende fejl:

Se NOTER.
ny_værdi er ikke korrekt initialiseret (en af tv_nsec falder udenfor intervallet nul til 999.999.999).
flag er ugyldig.

STANDARDER

Linux.

HISTORIK

Linux 2.6.25, glibc 2.8.

NOTER

Hvis vi antager det følgende scenarie for CLOCK_REALTIME- eller CLOCK_REALTIME_ALARM-stopuret, der blev oprettet med timerfd_create():

(1)
Stopuret er blevet startet (timerfd_settime()) med TFD_TIMER_ABSTIME- og TFD_TIMER_CANCEL_ON_SET-flagene;
(2)
En ej fortsættende ændring (f.eks. settimeofday(2)) er efterfølgende lavet på CLOCK_REALTIME-uret; og
(3)
kalderen kaldte igen timerfd_settime() for at bevæbne stopuret (uden først at lave en read(2) på fildeskriptoren).

I dette tilfælde sker der det følgende:

timerfd_settime() returnerer -1 med errno angivet til ECANCELED. (Dette gør det muligt for kalderen at vide at det tidligere stopur var påvirket af en ej fortsættende ændring til uret).
Stopuret er bevæbnet med succes med indstillingerne angivet i det andet timerfd_settime()-kald. (Dette var sandsynligvis et implementeringsuheld, men vil ikke blive rettet nu, i tilfælde af at der er programmer, der afhænger af denne opførelse).

FEJL

I øjeblikket understøtter timerfd_create() færre typer af ur-id'er end timer_create(2).

EKSEMPLER

Det følgende program opretter et stopur og overvåger så dets status. Programmet accepterer op til tre kommandolinjeargumenter. Det første argument angiver antallet af sekunder for et oprindelige udløb for stopuret. Det andet argument angiver intervallet for stopuret, i sekunder. Det tredje argument angiver antallet af gange programmet bør tillade at stopuret udløber før afslutning. Det andet og det tredje kommandolinjeargument er valgfrie.

Den følgende skalsession demonstrerer brugen af programmet:


$ a.out 3 1 100
0.000:	timer started
3.000:	read: 1; total=1
4.000:	read: 1; total=2
^Z                  # tast control-Z for at suspendere programmet
[1]+  Stopped                 ./timerfd3_demo 3 1 100
$ fg                # Genoptag afvikling efter nogle få sekunder
a.out 3 1 100
9.660:	read: 5; total=7
10.000:	read: 1; total=8
11.000:	read: 1; total=9
^C                  # tast control-C for at suspendere programmet

Programkilde

#include <err.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/timerfd.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
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:\t", secs, (nsecs + 500000) / 1000000); } int main(int argc, char *argv[]) {
int fd;
ssize_t s;
uint64_t expir, tot_expir, max_expir;
struct timespec now;
struct itimerspec new_value;
if (argc != 2 && argc != 4) {
fprintf(stderr, "%s init-secs [interval-secs max-num-expir]\n",
argv[0]);
exit(EXIT_FAILURE);
}
if (clock_gettime(CLOCK_REALTIME, &now) == -1)
err(EXIT_FAILURE, "clock_gettime");
/* Opret et CLOCK_REALTIME-absolut stopur med oprindelig
udløb og interval som angivet på kommandolinjen. */
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_expir = 1;
} else {
new_value.it_interval.tv_sec = atoi(argv[2]);
max_expir = 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\n");
for (tot_expir = 0; tot_expir < max_expir;) {
s = read(fd, &expir, sizeof(uint64_t));
if (s != sizeof(uint64_t))
err(EXIT_FAILURE, "read");
tot_expir += expir;
print_elapsed_time();
printf("read: %" PRIu64 "; total=%" PRIu64 "\n",
expir, tot_expir);
}
exit(EXIT_SUCCESS); }

SE OGSÅ

eventfd(2), poll(2), read(2), select(2), setitimer(2), signalfd(2), timer_create(2), timer_gettime(2), timer_settime(2), timespec(3), epoll(7), time(7)

OVERSÆTTELSE

Oversættere af denne manual til dansk Joe Hansen <joedalton2@yahoo.dk>

Denne oversættelse er gratis dokumentation; læs GNU General Public License version 3 eller nyere for ophavsretbetingelser. Der er INGEN ANSVAR.

Hvis du støder på fejl i oversættelsen af ​​denne vejledning, skal du sende en besked til debian-l10n-danish@lists.debian.org.

8. februar 2026 Linux man-pages 6.17