How to periodically execute a function in C ??

Hi,

I am looking for a C library feature, to which I can say execute a function every 10 seconds.

for Eg

#include <timer_lib.h>
fun1(){
      printf("I am still cool "); 
}

int main(){
   run(10,&fun1); // Should register & execute the function fun1 every 10 seconds
 return 0x0;
}

I am not interested in using the sleep function in a while loop or something..
Is there such a feature in the standard C library ??. I have heard about such facilities available on the kernel libraries.

here is one shot,

register the function that has to be executed frequently as handler to the SIGALRM signal

and raise the alarm periodically

I've seen the SIGALRM solution mentioned a few times, it's not good because it encourages heavyweight responses in signal handlers, as signals are asynchronous they can trash the heap if you are doing memory allocation/deallocation in the handler.

  1. use a simple loop
while (1) {
     sleep(10);
     do_stuff();
}
  1. do other stuff as well
while (1) {
      select with timeout
      if (time_is_ripe()) do_stuff();
}
  1. use a callback from a library
XtAppAddTimeout(app,interval,do_stuff,data);

// chronistic.h
struct Chronistic
{
Chronistic(int _seconds) : seconds(_seconds) {next(time(0));}
virtual bool operator()() = 0; // pure virtural, never call from c'tor or d'tor
private: int seconds;
protected:
bool trigger()
{
time_t now = time(0);
if (now > trigger_target) return next(now); // always true
else return false;
}
private:
time_t trigger_target;
bool next(time_t now) // must not be virtual, must not call anything virtual (it's used in the c'tor). Always returns true.
{
trigger_target=now+seconds;
return true;
}
};

// chronistic.cpp
#include <iostream>
#include <cstdlib>

#include <string>
#include "chronistic.h"

using namespace std;

struct MyChronFunction : Chronistic
{
MyChronFunction(int seconds) : Chronistic(seconds) {}
virtual bool operator()()
{
if (!trigger()) return false;
cout<<"Time to do something"<<endl;
return true;
}
};

int main(int argc, char *argv[])
{
MyChronFunction cronologic(90); // setup to execute every 90 seconds
while (true)
{
cronologic();
usleep(10); // prevents race condition
}

return EXIT_SUCCESS;
}

That is awful

(a) nothing like using C++ to make a simple problem complicated.

(b) nothing like using C++ to obscure the fact that you have a truely terrible solution

You basically have a polling loop executing every 10 microseconds, when you should be telling the operating system the maximum time you are prepared to go to sleep for and let the OS put your task to sleep and get on and do other things.

If you have a list of tasks, you should find the earliest that something needs to be done then sleep until that time.

I like C++. Wasn't trying to do anything real fancy with the os, just a simple polling check might suffice.

Thanks for the feedback.

There is nothing wrong with using C++, but don't use it like a magician's sleight of hand to obscure a poor implementation.

No problem.

What poor implementation? Did I make a mistake in the code? Does it not work?

Using a high speed polling loop with a 10 micro second delay (apparently to avoid a race condition) to schedule tasks that occur in seconds.

That means for every second, you will wake up and execute the loop 100,000 times before you will ever find anything to do. If you have to delay 10 seconds as was originally requested, your loop would have spun a million times before it had to do anything useful.

Simply using a variable for the usleep() parameter that was the number of microseconds between now and the next timed event would have been an excellent solution.

True, but then the function can only act as a cron manager. The object is meant to be used from within a game loop. That seems far more useful than a discrete utility designed only to sleep for specified number of milli seconds. Besides, the simple sleep method may not take into account how long it takes to execute the function before triggering again.

Anyway, it's just one of many ways to accomplish the task at hand. I didn't mean to strike a nerve.

I spent 3 months on something like this a few years ago. QA beat up on it pretty hard, it seemed to hold up well.

It may be fine code for a single user/single threaded/single application Playstation but not on a multiuser multiprocessing platform.

Also it's bad practice on a battery powered device as the goal is to do nothing as efficiently as possible, ie let the device go to sleep for the longest period.

interesting - I didn't even realize this was for use in a battery powered device. I guess there are a billion things it could be used for, and there are probably billion different ways to do it.

So, what is really the best (hopefully somewhat platform independent) way to accomplish this? Is there one? A project that I worked on a few years ago would have been best done if I had known how to really take advantage of a Sun kernel, but I didn't, and neither did anyone else at the shop, so we just used the clock. It held up well enough, but, we did consider exploring options using traps and signals.

WebKruncher, porter could be more diplomatic, but he does have a point. You are proposing something like:

trigger=time(NULL)+90;
while (1) {
         if (time(NULL)>trigger) {
                    trigger=time(NULL)+90;
                     do_something();
                     }
         usleep(10);
}

That is not a great way to arrange for something to happen every 90 seconds on any platform. If a process has nothing to do for 90 seconds, then it should do nothing during that 90 seconds. This is true on every platform. The problem is that you are busy looping waiting for 90 seconds to pass. If you replace "usleep(10)" with some code that does useful important work, then you basicly have a technique I would use to display a progress message as a very lengthy program runs. I don't care if the message is several seconds late. But the trigger test is in a main loop that is doing something useful. Take out the time test and my program remains useful. But take out your trigger test and you are left with:
while(1) usleep(10);
That puts quite a load on a system for no good reason.

If there is nothing to do in the loop but wait for 90 seconds to pass, I would simply use:

while (1) {
        do_something();
        sleep(90);
}

On every system I know, this is a much better solution than spinning in a loop waiting for 90 seconds to pass.

Why do want that loop running during the 90 second delay? Do you realize that the system is doing a lot of work that has no effect? If you are determined that you absolutely must have a loop spinning during the 90 second delay, you could improve the situation quite a bit by simply increasing usleep constant, say to 500000. Or replace it with sleep(1) or even sleep(10). You are still forcing the OS to run your process periodically. But at least not as often.

This might be about the coolest site I've ever seen. Anyway, diplomacy is over-rated :slight_smile:

I don't disagree at all about the performance hit. I came up with the C++ object just to pack all of whatever it's gonna do into something that can be tucked away in a generic library and offer an easy way to trigger something. I like it because it keeps all the dirty work of checking the clock out of the main code. So, the utility can look something like:

// xxx is each of sound, graphics_cache, file_activity, port_status, whatever_else
struct xxx_Manager : Chronisitcs
{
xxx_Manager(int ms) : Chronistics(ms) {}
virtual bool operator()();
}

bool xxx_Manager::operator()()
{
if (!trigger()) return false;
// it's time to do whatever an xxx manager should do
return true;
}

while (1)
{
// just do whatever you normally do...
// each line turns out to be a function object based on the Chonistics thingy
sound_manager();
graphic_cache_manager();
geometry_manager();
collision_manager();
file_activity_manager();
port_status_manager();
magic_spell_manager();
socket_service_manager();
whatever_else_manager();
// probably need some kind of system call here or you'll tank.
// usually a short sleep does the trick.
usleep(10);
}

...and all the logic of determining when to actually do the stuff is handled in the Chronistic guts. However it's done, it happens exactly the same way for every Chronistic derivative. And, of course then, you can have stacks and deques and maps of managed objects, and traverse them, sort them, update them in whatever order you want, index them, well, you get the point. It can get pretty interesting.

But, what I really want to know is, what is the best way to get the kernel to signal something periodically. And, can it be done without a worker thread?

Alas C++ is like the electric guitar which amplifies the mistakes as well as the good notes.

You don't need a ton of managers hard coded as you have, you can simply have a linked list of tasks that have to be performed together with the criteria for when to invoke them, an excellent example is how X11 Intrinsics manage the event loop allowing all manner of widgets to be supported in addition to file descriptor sinks, event timers and work procedures.

So when you want to add a new manager you don't have to change the code in the main event loop.

What OS does the iPhone use? :slight_smile:

Change your

usleep(10);

to

usleep(nextTimedEvent ? ( nextTimedEvent->when - now ) : kForever);

and you have solved your problem.

With UNIX, unless

(a) you are writing a simple filter program, or compiler, etc,

(b) one that is not interactive

(c) does not use networking

(d) is a multithreaded program

(e) a few more exceptions I can't immediately think of

the main loop of your program should be built directly or indirectly on either select or poll and you should be trying to determine the longest timeout value.

Do you know of any samples of select being used as a cron trigger?

Both ncurses and libXt have either select() or poll() at the heart of their mainloop/scheduler.

Hence KDE, Gnome, Motif, LessTif etc all sit on select or poll.

I'll have to look at that.
Can you do this on every OS?