.. include:: POSIX Timers: Introduction ========================== .. topic:: See also * :doc:`/trainings/material/soup/linux/sysprog/signals/index` * :doc:`/trainings/material/soup/linux/sysprog/posix-threads/index` .. topic:: Documentation * `man -s 2 timer_create `__ * `man -s 2 timer_delete `__ * `man -s 2 timer_settime `__ * `man -s 2 timer_gettime `__ * `man -s 2 timer_getoverrun `__ * `man -s 3 sigevent `__ Overview -------- * One-shot and periodic variants * Nanosecond granularity * Parameterizable clock (see :doc:`/trainings/material/soup/linux/sysprog/timers/clocks/index`) * 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 :doc:`/trainings/material/soup/linux/sysprog/signals/sync/index`) * Notification using threads (see :doc:`/trainings/material/soup/linux/sysprog/posix-threads/index`) Creation And Deletion --------------------- .. topic:: Documentation * `man -s 2 timer_create `__ * `man -s 2 timer_delete `__ * `man -s 3 sigevent `__ .. code-block:: c #include 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 sigevent`` * Optional callback parameter "Arming" A Timer ---------------- .. topic:: Documentation * `man -s 2 timer_settime `__ .. code-block:: c #include 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 |longrightarrow| must "arm" first * Oneshot or periodic (see :doc:`../posix-oneshot-periodic/index`) ``struct sigevent`` ------------------- * ``struct sigevent`` - timer "callback" specification * A bit convoluted * Not all fields are valid in all circumstances **Notification type** * ``sigev_notify == SIGEV_SIGNAL`` * ``sigev_signo``: signal number - user selectable, e.g. ``SIGRTMIN+7``, or ``SIGUSR1`` * Important: even when a realtime signal is chosen (see :ref:`here `), *multiple expirations are not queued* * ``sigev_notify == SIGEV_THREAD`` * ``sigev_notify_function``: callback function called in a separate thread * ``sigev_notify_attributes``: attributes for thread creation (see :doc:`here `) * ``sigev_notify == SIGEV_NONE``: must poll using ``timer_gettime()`` **More callback information** * ``sigev_value``, of type .. code-block:: c union sigval { int sival_int; void *sival_ptr; }; * ``SIGEV_SIGVAL``: passed to signal handler when installed as ``SA_SIGINFO`` (see later) * ``SIGEV_THREAD``: passed as argument to thread callback function, ``sigev_notify_function`` (see later) .. _sysprog-posix-timer-limit: Limits, Anywhere? ----------------- * From `man -s 2 timer_create `__ .. code-block:: text :caption: ``NOTES`` section 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 .. code-block:: console $ ulimit -a ... pending signals (-i) 62209 ... * Reality check .. literalinclude:: code/maxtimers.cpp :language: c++ :caption: :download:`code/maxtimers.cpp` .. code-block:: console $ ./sysprog-timers-maxtimers timer_create: Resource temporarily unavailable 62207 timers created