timerfd_create(2)

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

BIBLIOTEK
C-standardbibliotek (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:

CLOCK_REALTIME
    Et realtids ur, der kan angives for hele systemet.

CLOCK_MONOTONIC
    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.

CLOCK_BOOTTIME (siden Linux 3.15)
    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.

CLOCK_REALTIME_ALARM (siden Linux 3.11)
    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.

CLOCK_BOOTTIME_ALARM (siden Linux 3.11)
    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():

TFD_NONBLOCK
    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.

TFD_CLOEXEC
    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:

TFD_TIMER_ABSTIME
    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.

TFD_TIMER_CANCEL_ON_SET
    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:

    TFD_IOC_SET_TICKS (siden Linux 3.17)
        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:

EINVAL
    clockid er ikke gyldig.

EINVAL
    flag er ugyldig; eller, i Linux 2.6.26 eller tidligere, flag er forskellig fra nul.

EMFILE
    Begrænsningen per proces for antallet af åbne fildeskriptorer er blevet nået.

ENFILE
    Systemets begrænsning på det samlede antal åbne filer er nået.

ENODEV
    Kunne ikke montere (intern) anonym iknude-enhed.

ENOMEM
    Der var utilstrækkelige kernehukommelse til at oprette stopuret.

EPERM
    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:

EBADF
    fd er ikke en gyldig filbeskrivelse.

EFAULT
    ny_værdi, gl_værdi eller nuv_værdi er ikke en gyldig peger.

EINVAL
    fd er ikke en gyldig timerfd-fildeskriptor.

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

ECANCELED
    Se NOTER.

EINVAL
    ny_værdi er ikke korrekt initialiseret (en af tv_nsec falder udenfor intervallet nul til 999.999.999).

EINVAL
    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: %w64u; total=%w64u\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 (https://www.gnu.org/licenses/gpl-3.0.html) 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.