POSIX Timers: Introduction#
Overview#
One-shot and periodic variants
Nanosecond granularity
Parameterizable clock (see Clocks, And Points In Time)
Absolute time-points and relative time-intervals
Dynamically created (
timer_t, see here)Notification using freely choosable signals (which can be waited for synchronously for that matter; see Synchronous Signal Handling)
Notification using threads (see POSIX Threads)
Creation And Deletion#
#include <time.h>
int timer_create(clockid_t clockid,
struct sigevent *_Nullable restrict sevp,
timer_t *restrict timerid);
int timer_delete(timer_t timerid);
“Callback” configuration via
struct sigeventOptional callback parameter
“Arming” A Timer#
#include <time.h>
int timer_settime(timer_t timerid, int flags,
const struct itimerspec *restrict new_value,
struct itimerspec *_Nullable restrict old_value);
After creation, a timer is idle ⟶ must “arm” first
Oneshot or periodic (see POSIX Timers: Arming (Oneshot/Periodic))
struct sigevent#
struct sigevent- timer “callback” specificationA bit convoluted
Not all fields are valid in all circumstances
Notification type
sigev_notify == SIGEV_SIGNALsigev_signo: signal number - user selectable, e.g.SIGRTMIN+7, orSIGUSR1Important: even when a realtime signal is chosen (see here), multiple expirations are not queued
sigev_notify == SIGEV_THREADsigev_notify_function: callback function called in a separate threadsigev_notify_attributes: attributes for thread creation (see here)
sigev_notify == SIGEV_NONE: must poll usingtimer_gettime()
More callback information
sigev_value, of typeunion sigval { int sival_int; void *sival_ptr; };
SIGEV_SIGVAL: passed to signal handler when installed asSA_SIGINFO(see later)SIGEV_THREAD: passed as argument to thread callback function,sigev_notify_function(see later)
Limits, Anywhere?#
-
NOTESsection#The kernel preallocates a "queued real-time signal" for each timer created using timer_create(). Consequently, the number of timers is limited by the RLIMIT_SIGPENDING resource limit (see setrlimit(2)).
A-ha
Limit of pending signals
$ ulimit -a ... pending signals (-i) 62209 ...
Reality check
#include <signal.h> #include <time.h> #include <print> int main() { int ntimers = 0; while (true) { timer_t timer; sigevent event = {0}; event.sigev_notify = SIGEV_SIGNAL; event.sigev_signo = SIGRTMIN; int rv = timer_create(CLOCK_MONOTONIC, &event, &timer); if (rv == -1) { perror("timer_create"); break; } ntimers++; } std::println("{} timers created", ntimers); return 0; }
$ ./sysprog-timers-maxtimers timer_create: Resource temporarily unavailable 62207 timers created