gozde baris
gozde baris

Reputation: 55

Call function periodically without using threads and sleep() method in c

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?

Upvotes: 3

Views: 12731

Answers (6)

Some programmer dude
Some programmer dude

Reputation: 409442

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.


Please note that this make the assumption that time_t is an integral type, which for at least 99.999% of of all cases it will be.

It also makes the assumption that time returns a value with second-only resolution. Which again it will be in at least 99.999% of all cases.

Lastly note that the code show is rather incomplete and was written only as a demonstration. It shouldn't be used "as-is".

Upvotes: 0

stevea
stevea

Reputation: 236

The most accurate solution in my tests from from the following code#include

<stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <time.h>
#include <unistd.h>
#include <sys/timerfd.h>

void *
say_hello()
{
    int rc, fd;
    struct itimerspec myitime;
    int64_t buffer;

    fd = timerfd_create(CLOCK_REALTIME, 0);

    // every 3 seconds
    myitime.it_interval.tv_sec = 3;
    myitime.it_interval.tv_nsec = 0;

    // start at NEXT full second
    rc = clock_gettime(CLOCK_REALTIME, &(myitime.it_value));
    myitime.it_value.tv_sec += 1;
    myitime.it_value.tv_nsec = 0;

    rc = timerfd_settime(fd, TFD_TIMER_ABSTIME, &myitime, NULL) ;

    // wait for input from fd, then print hello
    while(true) {
    read(fd, &buffer, 8);
    printf("Hello\n");
    }

    return NULL;
}

int main()
{
    say_hello();
    // never returns
    return 0;
}

Of course say_hello can be spawned as a thread.

The timerfs call, on my unloaded system produces a printer output with a 5.3 microsecond RMS variation. The evtimer method produces a output with a 319 microsecond RMS variation.

Upvotes: 0

Davide Berra
Davide Berra

Reputation: 6568

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;
}

Upvotes: 4

kfunk
kfunk

Reputation: 2092

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 :)

Upvotes: 0

Mats Petersson
Mats Petersson

Reputation: 129524

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.

Upvotes: 4

Maxiking1011
Maxiking1011

Reputation: 95

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 :)

Upvotes: 0

Related Questions