timer_create(2)

NAVN
timer_create - opret et POSIX per proces-stopur

BIBLIOTEK
Realtidsbibliotek (librt, -lrt)

SYNOPSIS
#include <signal.h>           /* Definition af SIGEV_*-konstanter */
#include <time.h>

int timer_create(clockid_t clockid,
                 struct sigevent *_Nullable restrict sevp,
                 timer_t *restrict timerid);

    Feature Test Macro Requirements for glibc (se feature_test_macros(7)):

timer_create():
    _POSIX_C_SOURCE >= 199309L

BESKRIVELSE
timer_create() opretter et nyt per proces-intervalstopur. Id'et for det nye stopur returneres i mellemlageret der peger på timerid, der skal være en ikke-null peger. Dette id er unik i processen, indtil stopuret slettes. Det nye stopur er oprindelig afvæbnet.

Argumentet clockid angiver uret, som det nye stopur bruger til at måle tiden. Kan angives som en af de følgende værdier:

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_PROCESS_CPUTIME_ID (siden Linux 2.6.12)
    Et ur der måler (bruger og system) cpu-tid forbrugt af (alle trådene i) den kaldende proces.

CLOCK_THREAD_CPUTIME_ID (siden Linux 2.6.12)
    Et ur der måler (bruger og system) cpu-tid forbrugt af den kaldende tråd.

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

CLOCK_TAI (siden Linux 3.10)
    Et ur for systemet udledt fra wall-clock-tiden men som tæller springende sekunder.

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

Udover de ovenstående værdier kan clockid angives som clockid returneret af et kald til clock_getcpuclockid(3) eller pthread_getcpuclockid(3).

Argumentet sevp peget på en sigevent-struktur, der angiver hvordan kalderen skal blive påmindet når stopuret udløber. For defintionen og generelle detaljer for denne struktur, se sigevent(3type).

Feltet sevp.sigev_notify kan have de følgende værdier:

SIGEV_NONE
    Påmind ikke asynkront når stopuret udløber. Status for stopuret kan overvåges via timer_gettime(2).

SIGEV_SIGNAL
    Ved stopursudløb opret signalet sigev_signo for processen. Se sigevent(3type) for generellle detaljer. Feltet si_code for strukturen siginfo_t vil blive angivet til SI_TIMER. På ethvert tidspunkt er mindst et signal i kø til processen for et angivet stopur; se timer_getoverrun(2) for yderligere detaljer.

SIGEV_THREAD
    Ved stopursudløb, igangsæt sigev_notify_function som var det startfunktionen for en ny tråd. Se sigevent(3type) for detaljer.

SIGEV_THREAD_ID (Linux-specifik)
    Som for SIGEV_SIGNAL, men signalet er målrettet tråden hvis id er angivet i sigev_notify_thread_id, der skal være en tråd i den samme proces som kalderen. Feltet sigev_notify_thread_id angiver en kernetråd-id, det vil issge, værdien returneret af clone(2) eller gettid(2). Dette flag er kun lavet for brug af trådbiblioteker.

Angivelse af sevp som NULL svarer til at angive en peger til en sigevent-struktur hvori sigev_notify er SIGEV_SIGNAL, sigev_signo er SIGALRM og sigev_value.sival_int er stopur-id'et.

RETURVÆRDI
Ved succes, timer_create() returnerer 0 og id'et for det nye stopur er placeret i *timerid. Ved fejl, -1 returneres og errno angives for at indikere fejlen.

FEJL

EAGAIN
    Midlertidig fejl under kerneallokering af stopurstrukturer.

EINVAL
    Ur-id, sigev_notify, sigev_signo eller sigev_notify_thread_id er ugyldig.

ENOMEM
    Kunne ikke allokere hukommelse.

ENOTSUP
    Kernen understøtter ikke oprettelse af et stopur mod dette clockid.

EPERM
    clockid var CLOCK_REALTIME_ALARM eller CLOCK_BOOTTIME_ALARM men kalderen havde ikke funktionaliteten CAP_WAKE_ALARM.

VERSIONER

  C-bibliotek/kerne-forskelle
Dele af implementeringen af POSIX-stopurs-API'en tilbydes af glibc. Specielt:

•   Meget af funktionaliteten for SIGEV_THREAD er implementeret i glibc, frem for i kernen. (Dette er nødvendigt da tråden involveret i at håndtere påmindelsen er en, der skal håndteret af C-bibliotekets POSIX-trådimplementering). Selvom påmindelsen leveret til processen er via en tråd, så bruger NPTL-implementeringen internt en sigev_notify-værdi sammen med et realtids signal, der er reserveret af implementeringen (se nptl(7)).

•   Implementeringen af standardtilfældet hvor evp er NULL håndteres inde i glibc, der igangsætter det underliggende systemkald med egnet udfyldt sigevent-struktur.

•   Stopur-id'et præsenteret på brugerniveau vedligeholdes af glibc, der oversætter disse id'er til stopurets id'er anvendt af kernen.

STANDARDER
POSIX.1-2024.

HISTORIK
Linux 2.6. POSIX.1-2001.

Før Linux 2.6 tilbød glibc en ufuldstændig brugerrumsimplementering (kun CLOCK_REALTIME-stopure) via POSIX-tråde og før glibc 2.17, benytter implementeringen denne teknik på systemer, der afvikler kerner ældre end Linux 2.6.

NOTER
Et program kan oprette flere intervalstopure via timer_create().

Stopure arves ikke af underprocessen for en fork(2), og afvæbnes og slettes under en execve(2).

Kernen præallokerer et »køet realtids signal« for hvert stopur oprettet via timer_create(). Som konsekvens er antallet af stopure begrænset af ressourcebegrænsningen RLIMIT_SIGPENDING (se setrlimit(2)).

Stopurene oprettet af timer_create() kendes ofte som »POSIX-(interval)stopure. POSIX-stopurs-API'en består af de følgende grænseflader:

timer_create()
    Opret et stopur.

timer_settime(2)
    Bevæbn (start) eller afvæbn (stop) et stopur.

timer_gettime(2)
    Hent tilbageværende tid indtil det næste udløb for et stopur, sammen med intervalindstillingen for stopuret.

timer_getoverrun(2)
    Returner overløbsantallet for det sidste stopursudløb.

timer_delete(2)
    Afvæbn og slet et stopur.

Siden Linux 3.10 kan filen /proc/pid/timers bruges til at vise POSIX-stoprurene for processen med PID pid. Se proc(5) for yderligere information.

Siden Linux 4.10 er understøttelse for POSIX-stopure et tilvalg, der kan konfigureres og er aktiveret som standard. Kerneunderstøttelse kan deaktiveres via tilvalget CONFIG_POSIX_TIMERS.

EKSEMPLER
Programmet nednefor bruger to argumenter: en soveperiode i sekunder og en stopursfrekvens i nanosekunder. Programmet etablerer et håndtag for signalet, det bruger for stopuret, blokerer det signal, opretter og bevæbner et stopur, der udløber med den anførte frekvens, sover i det anførte antal sekunder og fjerner så blokeringen på stopurssignalet. Under antagelse af at stopuret udløb mindst en gang mens programmet sov, vil signalhåndteringen blive igangsat og håndteringen viser lidt information om stopurspåmindelsen. Programmet afslutter efter en igangsættelse af signalhåndteringen.

I det følgende eksempel sover programmet i 1 sekund, efter et stopur er oprettet med en frekvens på 100 nanosukneder. På det tidspunkt hvor signalet får fjernet og leveret sit signal, har der været omkring ti millioner overløb.

    $ ./a.out 1 100;
    Etablerer håndtering for signal 34
    Blokerer signal 34
    stopur-id er 0x804c008
    Sover i 1 sekund
    Fjerner blokering for signal 34
    Fangede signal 34
        sival_ptr = 0xbfb174f4;     *sival_ptr = 0x804c008
        overløbsantal = 10004886

  Programkilde
    #include <err.h>
    #include <signal.h>
    #include <stdint.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #include <unistd.h>

    #define CLOCKID CLOCK_REALTIME
    #define SIG SIGRTMIN

    static void
    print_siginfo(siginfo_t *si)
    {
        int      or;
        timer_t  *tidp;

        tidp = si->si_value.sival_ptr;

        printf("    sival_ptr = %p; ", si->si_value.sival_ptr);
        printf("    *sival_ptr = %#jx\n", (uintmax_t) *tidp);

        or = timer_getoverrun(*tidp);
        if (or == -1)
            err(EXIT_FAILURE, "timer_getoverrun");

        printf("    overrun count = %d\n", or);
    }

    static void
    handler(int sig, siginfo_t *si, void *uc)
    {
        /* Bemærk: kald af printf() fra en signalhåndtering er ikke sikkert
           (og bør ikke gøres i produktionsprogrammer), da
           printf() ikke er asynkron-signal-sikker; se signal-safety(7).
           Alligevel så bruger vi printf() her som en simpel måde at
           vise at håndteringen blev kaldt.  */

        printf("Caught signal %d\n", sig);
        print_siginfo(si);
        signal(sig, SIG_IGN);
    }

    int
    main(int argc, char *argv[])
    {
        timer_t            timerid;
        sigset_t           mask;
        long long          freq_nanosecs;
        struct sigevent    sev;
        struct sigaction   sa;
        struct itimerspec  its;

        if (argc != 3) {
            fprintf(stderr, "Brug: %s <sleep-secs> <freq-nanosecs>\n",
                    argv[0]);
            exit(EXIT_FAILURE);
        }

        /* Etabler håndtering for stopurssignal.  */

        printf("Etablerer håndtering for signal %d\n", SIG);
        sa.sa_flags = SA_SIGINFO;
        sa.sa_sigaction = handler;
        sigemptyset(&sa.sa_mask);
        if (sigaction(SIG, &sa, NULL) == -1)
            err(EXIT_FAILURE, "sigaction");

        /* Bloker stopursignalet midlertidigt.  */

        printf("Blokerer signal %d\n", SIG);
        sigemptyset(&mask);
        sigaddset(&mask, SIG);
        if (sigprocmask(SIG_SETMASK, &mask, NULL) == -1)
            err(EXIT_FAILURE, "sigprocmask");

        /* Opret stopuret.  */

        sev.sigev_notify = SIGEV_SIGNAL;
        sev.sigev_signo = SIG;
        sev.sigev_value.sival_ptr = &timerid;
        if (timer_create(CLOCKID, &sev, &timerid) == -1)
            err(EXIT_FAILURE, "timer_create");

        printf("stopur-id er %#jx\n", (uintmax_t) timerid);

        /* Start stopuret.  */

        freq_nanosecs = atoll(argv[2]);
        its.it_value.tv_sec = freq_nanosecs / 1000000000;
        its.it_value.tv_nsec = freq_nanosecs % 1000000000;
        its.it_interval.tv_sec = its.it_value.tv_sec;
        its.it_interval.tv_nsec = its.it_value.tv_nsec;

        if (timer_settime(timerid, 0, &its, NULL) == -1)
             err(EXIT_FAILURE, "timer_settime");

        /* Sov i en priode; i perioden kan stopuret udløbe
           flere gange.  */

        printf("Sover i %d sekunder\n", atoi(argv[1]));
        sleep(atoi(argv[1]));

        /* Lås stopursignalet op, så at stopurspåmindelsen
           kan leveres.  */

        printf("Fjerner blokering for signal %d\n", SIG);
        if (sigprocmask(SIG_UNBLOCK, &mask, NULL) == -1)
            err(EXIT_FAILURE, "sigprocmask");

        exit(EXIT_SUCCESS);
    }

SE OGSÅ
clock_gettime(2), setitimer(2), timer_delete(2), timer_getoverrun(2), timer_settime(2), timerfd_create(2), clock_getcpuclockid(3), pthread_getcpuclockid(3), pthreads(7), sigevent(3type), signal(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.