1

The title says it all. I have seen solutions in C++. For example, this one and some which (also C++) are rather old. I am open to using glib or any other opensource library. I care only for Linux implementation.

I came across glib's timer functions but they are all synchronous in nature and not close to what setTimeout() does.

I can think of one solution of having a separate thread which continually, in a loop, checks if a timer, such as the one provided by Glib, has expired and then fire the corresponding function. Of course, that would be ridiculously inefficient.

I also came across this one here which suggests the use of alarm(2). It can be used but granularity is in seconds only.

EDIT: Alas alarm() cancels any previously set alarm()

15
  • 1
    Have a look at the alarm and settimer functions. alarm generates signals so you'll need a signal handler. Commented Feb 23, 2020 at 16:49
  • 1
    I added the linux tag since you say that's the OS you care about, and since this question won't have an answer in standard C. Commented Feb 23, 2020 at 17:22
  • 1
    Note that if you go from single-threaded event based app architecture to multithreaded apps, be prepared for a world of pain. I'd look for "C event library" instead of threads for stuff like this. Commented Feb 24, 2020 at 8:11
  • 1
    @asinix normally in Linux, event loop is programmed around select (or equivalent) system call, with timeout set to next timer event. No interrupting timer mechanism or signals needed. There can be an arbitrary number of timers. Commented Feb 24, 2020 at 14:32
  • 1
    @hyde Thats it!! Thanks a lot. Now I understand why you were talking about event loop regarding timers! Certainly an elegant solution. Commented Feb 24, 2020 at 16:21

2 Answers 2

1

You mention that you need more than one timer in your process, so you might want the POSIX timer_* family of functions (timer_create, timer_settime, etc). They have nanosecond granularity. You can specify a few different actions for when the timer expires: raise a signal, or call a function from a separate thread. You have to link with -lrt to use these functions.

There is also timerfd_create, which let you detect timer expiration by a file becoming readable, using poll or select or their relatives.

Sign up to request clarification or add additional context in comments.

8 Comments

I am going through it and it appears to be exactly what I am looking for (and a lot more!).
From the man page for sigevent: "..SIGEV_THREAD ...Among the implementation possibilities here are that each timer notification could result in the creation of a new thread, or that a single thread is created to receive all notifications.." Creating a thread for each notification would be an overkill to say the least. Is there a way to have "a single thread created to receive all notifications" ?
@asinix: From a look at the glibc source, the latter is what it actually does. It creates one helper thread which does nothing except sit and wait for signals. Then it uses SIGEV_THREAD_ID to ensure that the timer signal goes to the helper thread, which is told to call your function when your timer goes off.
This message just means that gdb is trying to show you the source line where the crash occurs, but it was inside glibc code and it doesn't know where to find the glibc source code. You could install the source somewhere and use the dir command in gdb to tell it where they are, which might help in debugging, but their absence isn't the cause of your crash. You should probably ask a separate question about that, with a complete test case.
But it either means you are calling timer_create incorrectly (read its man page carefully) or else that there is a bug in glibc. By Jeff Atwood's First Rule you should assume the first case until you can prove otherwise...
|
1

If you want to use GLib and its timeout sources (g_timeout_add(), g_timeout_add_seconds(), etc.), then you will need to run a GLib main loop (GMainLoop) and run the rest of your application in a main loop callback too. This will be quite a large change if your application isn’t already written in an event-driven style, but would be necessary for polling sockets or running a UI anyway.

There’s an example of how to use a timeout source in an application here.

Note that GLib’s timer API (g_timer_*()) is not for running callbacks after a certain timeout, it’s for timing how long something takes (like a stopwatch). It’s not relevant here.

3 Comments

I generally prefer to use basic Linux system calls and avoid using other libraries unless absolutely required because I am not planning to port my code to any other platform. I already have my own event loop per thread and introducing GLib main loop will be an over-kill just for this requirement. The solution suggested by Nate works just fine. I will, however, look into the Glib functions you suggested.
Sure, GLib is only one solution — I thought it merited explanation in an answer, though, since the question is tagged as glib and you mentioned its timer functions explicitly in the question. :)
For me, every explanation is educational as I am not an expert in this area. I find a lot of solutions hidden somewhere in GLib so I did tag it just in case there was no other easy solution.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.