3

I want to call a function, lets say every 10 or 20 seconds. When I searched, I came up with threads and sleep() method everywhere.

I also checked for time and clock classes in C but I could not find anything helpful specific to my question.

What is the most simple way to call functions periodically?

Jens
  • 69,818
  • 15
  • 125
  • 179
gozde baris
  • 55
  • 1
  • 1
  • 6
  • 1
    Simple search found [this](http://stackoverflow.com/questions/3557221/how-do-i-measure-time-in-c). –  Feb 12 '13 at 12:05
  • 3
    Why are you ruling out threads / sleep? This sounds like a "I want to do 'X' but without doing [insert good way to to 'X']" question. – JasonD Feb 12 '13 at 12:06
  • The simplest way is `while(1) { sleep(10); function(); }`, so you should specify what's wrong with `sleep` (for the requirement "not to use sleep" we have plenty of alternatives doing essentially the same thing). – Anton Kovalenko Feb 12 '13 at 12:06
  • It depends on your system and available libraries. What are you using? – KBart Feb 12 '13 at 12:10
  • 1
    You talk of methods and classes. Are you sure you have a C problem and not a C++ problem? – Jens Feb 12 '13 at 12:13
  • I think checking now and again time passed is just the same as sleep() or even worse. – qben Feb 12 '13 at 12:16
  • You might like ot read here: http://linux.die.net/man/2/alarm on how to setup a signal to be sent to your process after a certain amount of time. Then read here http://linux.die.net/man/2/signal on how to setup a signal handler. But be aware there that are limitations on what functions a signal handler may call. Regarding the latter please read here: http://linux.die.net/man/7/signal – alk Feb 12 '13 at 12:30
  • Simpler? How much simpler can you get than a Sleep() loop? – Martin James Feb 12 '13 at 12:33

5 Answers5

4

Most operating systems have a way to "set an alarm" or "set a timer", which will call a function of yours at a given time in the future. In linux, you'd use alarm, in Windows you'd use SetTimer.

These functions have restrictions on what you can do in the function that gets called, and you almost certainly will end up with something that has multiple threads in the end anyway - although the thread may not be calling sleep, but some wait_for_event or similar function instead.

Edit: However, using a thread with a thread that contains:

while(1) 
{
   sleep(required_time); 
   function(); 
}

The problem is solved in a very straight forward way to solve the problem, and makes it very easy to handle.

Mats Petersson
  • 126,704
  • 14
  • 140
  • 227
  • +1, and with alarm/setitimer you get all "joys" of async-signal-safety restriction, so there's not much that this function could do if this method is used. – Anton Kovalenko Feb 12 '13 at 12:15
4

Use libevent, in my opinion, is the cleaner solution because, in the meantime, you can do other operations (even other timed functions)

look at this simple and self explaining example that print out Hello every 3 seconds:

#include <stdio.h>
#include <sys/time.h>
#include <event.h>

void say_hello(int fd, short event, void *arg)
{
  printf("Hello\n");
}

int main(int argc, const char* argv[])
{
  struct event ev;
  struct timeval tv;

  tv.tv_sec = 3;
  tv.tv_usec = 0;

  event_init();
  evtimer_set(&ev, say_hello, NULL);
  evtimer_add(&ev, &tv);
  event_dispatch();

  return 0;
}
Davide Berra
  • 6,387
  • 2
  • 29
  • 50
1

A naive solution would be something like this:

/* Infinite loop */
time_t start_time = time(NULL);
for (;;)
{
    time_t now = time(NULL);

    time_t diff = now - start_time;

    if ((diff % 10) == 0)
    {
        /* Ten seconds has passed */
    }

    if ((diff % 20) == 0)
    {
        /* Twenty seconds has passed */
    }
}

You might want a flag that tells if the function has been called, or it will be called several times during the single second (diff % 10) == 0 is true.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • This has the drawback of "missing" if the time capture isn't happending every second (at least). Say for example if we have user input... – Mats Petersson Feb 12 '13 at 12:12
  • This won't work on implementations where `time_t` is a floating point type because `%` needs integer operands. – Jens Feb 12 '13 at 12:19
  • @MatsPetersson Of course. I _do_ state it's a naive solution. :) – Some programmer dude Feb 12 '13 at 12:35
  • @Jens I've never ever encountered a platform where `time_t` is _not_ an integer, and it's unlikely that I (or most programmers) ever will. – Some programmer dude Feb 12 '13 at 12:37
  • @JoachimPileborg So you make assumptions, which are the mother of all screw-ups. I work in the space business where GPS time may very well be fractional. We'd have our ass kicked if we were to excuse a lost satellite or launch vehicle with "I've never encountered and thought it unlikely that ..." All that counts is the spec. The spec for time_t is "a real type" (C11) or "arithmetic type" (C99). – Jens Feb 12 '13 at 15:58
  • @Jens Even when working in "space business" is `time_t` a type capable of handling the requirements and precision you need, or do you use types and APIs better suited for that problem space and let `time_t` be the traditional integer? Also, while making assumptions may be bad, if none are to be made then programming would be a couple of magnitudes harder and very few would be able to do it (think back to the age of programmers wearing white lab coats in big computer rooms). – Some programmer dude Feb 12 '13 at 16:51
  • @JoachimPileborg I'll never understand why people keep defending their unreliable and unportable programming, especially in the face of existing Standard C functions to compute time differences. Even if you assume time_t is integral, you can't assume it counts seconds. To compute time differences the Standard C `difftime()` must be used. As for hardness, **programming properly is hard, it's an engineering profession**, programming junk is easy, though. – Jens Feb 12 '13 at 18:27
1

Try this:

while(true) {
   if(System.getNanotime % 20 == 0) {
      myFunction();
   } 
}

This is in Java-Syntax, i didn't program c since more than 5 years, but maybe it helps you :)

Maxiking1011
  • 97
  • 1
  • 2
  • 10
0

Simple:

#include <stdio.h>
#include <unistd.h>

int main(int argc, const char** argv)
{
    while(1)
    {
        usleep(20000) ;
        printf("tick!\n") ;
    }
}

Note that usleep() will of course block :)

kfunk
  • 2,002
  • 17
  • 25
  • Won't compile because is missing. Why are people so obsessed with while(true) or while(1) when a simple for(;;) would do? – Jens Feb 12 '13 at 12:21
  • 3
    Fixed. It's a matter of taste, after all. – kfunk Feb 12 '13 at 12:23
  • Everybody with a taste for constants in boolean expressions needs a taste reevaluation :-) My lint flags them, rightfully. They're ugly as hell. – Jens Feb 12 '13 at 16:04