I needed a timer that after some time expires an event, for example std :: function. In Win32 API and in C #, I very often used such timers, but here I couldn’t find them right away -_-. There was an idea to implement such a class by running the flow all the time and checking the current time all the time, but in my project, performance is very important and it seems to me not to be the most reasonable solution. From third-party libraries I can only use boost (I know that there is a similar timer in qt, but I can’t use it at all). Please tell me where I can get in Linux a cheap in terms of performance timer for events which can be subscribed to by std :: function <___> functors.

    4 answers 4

    Linux has posix function

    #include <sys/time.h> int setitimer(int which, const struct itimerval *value, struct itimerval *ovalue); 

    to reset the timer, the program receives a signal SIGALRM which can be processed by your function, which is put on the signal handler using the function

     #include <signal.h> int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact); 
    • 2
      Just to mention that the actions available from such a signal handler are strictly limited. Including you cannot allocate / free memory, call most of the code from the standard library, etc. With the exception of some special situations and (very) old code, the use of (asynchronous) signals should be avoided. - VTT
    • Many thanks, now I will try to implement. - mrFieldy

    You can use the int timer_create function (clockid_t clockid, struct sigevent * sevp, timer_t * timerid); .

    The sigevent structure has a void (*sigev_notify_function) (union sigval); field void (*sigev_notify_function) (union sigval); which may contain the address of the function called in a separate thread when the timer is triggered.

    • Thanks, I'll try it now too. - mrFieldy

    Kamrad @yaroslav gave the exact and correct answer. But this option is quite low-level. Although not requiring additional libraries from the side. But it also has a number of nuances related to the context of signal processing (study this question if you use this method).

    You can use timers from libev, let's say.

    Or use Asio (as a separate self-contained library or from Boost). The second is especially relevant when using C ++ 11/14/17 / etc.

    And if you work with graphics through Gtk + / Qt, then they have their own functionality, with which you can solve your problem. EMNIP and in glib (to which the graph and is not needed) there is something similar.

    • FYI, livev! = Livevent, which is mentioned below ;-) - Monah Tuk

    You can use libevent

     #include <event.h> #include <sys/time.h> #include <iostream> void On_Timer(int fd, short id, void * param) noexcept { ::std::cout << "Time" << ::std::endl; auto const p_event{static_cast<struct ::event *>(param)}; ::event_del(p_event); // отписываем событие, циклу больше нечего будет делать и он вернет управление в main } int main(int argc, const char* argv[]) { auto const p_event_base{::event_base_new()}; auto const p_event{::event_new(p_event_base, -1, EV_PERSIST, &::On_Timer, ::event_self_cbarg())}; struct ::timeval tv{1, 0}; // 1 секунда ::evtimer_add(p_event, &tv); // подписываем событие ::event_dispatch(); // запускаем цикл ::event_free(p_event); ::event_base_free(p_event_base); return 0; } 
    • Then I can try for myself, but in the current project it will be very hard to add something from the outside (for bureaucratic reasons). - mrFieldy