Scroll to navigation

timer_create(2) System Calls Manual timer_create(2)

NAVN

timer_create - opret et POSIX per proces-stopur

BIBLIOTEK

Real-time library (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:

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

Påmind ikke asynkront når stopuret udløber. Status for stopuret kan overvåges via timer_gettime(2).
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.
Ved stopursudløb, igangsæt sigev_notify_function som var det startfunktionen for en ny tråd. Se sigevent(3type) for detaljer.
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

Midlertidig fejl under kerneallokering af stopurstrukturer.
Ur-id, sigev_notify, sigev_signo eller sigev_notify_thread_id er ugyldig.
Kunne ikke allokere hukommelse.
Kernen understøtter ikke oprettelse af et stopur mod dette clockid.
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:

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

29. oktober 2025 Linux man-pages 6.17