create a timer

Sometimes, you need a timer function. For example, you wanna check some live status every 5 seconds. By using sleep() is just not the way of doing, because the programs suppose to process for other things within this 5 seconds. We need a non-blocking timer function for that.

I created two functions uses timeval structure, and gettimeofday(), does the job of timer. Bellow is the code that illustrate how it works:

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

int SetTimer(struct timeval &tv, time_t sec)
{
    gettimeofday(&tv,NULL);
    tv.tv_sec+=sec;

    return 1;
}

int CheckTimer(struct timeval &tv, time_t sec)
{
    struct timeval ctv;
    gettimeofday(&ctv,NULL);

    if( (ctv.tv_sec &gt; tv.tv_sec) )
    {
        gettimeofday(&tv,NULL);
        tv.tv_sec+=sec;
        return 1;
    }
    else
        return 0;
}

int main()
{
    struct timeval tv;
    SetTimer(tv,5); //set up a delay timer
    printf("start counting.\n");
    while(1)
        if (CheckTimer(tv,5)==1)
            printf("Welcome to cc.byexamples.com\n");
    return 0;
}

SetTimer() are use to set timer for the first time, and CheckTimer() use to check for the previous timer value. If it is times up, it will returns 1 at the same time initiate a new time value based on what you pass in at second argument. By doing that, is to allow flexibility of changing time interval value.

The minimum value for this timer is one second, for timer that works for less than one seconds, replace the SetTimer and CheckTimer as bellow:

int SetTimer(struct timeval &tv, int usec)
{
    gettimeofday(&tv,NULL);
    tv.tv_usec+=usec;

    return 1;
}

int CheckTimer(struct timeval &tv, int usec)
{
    struct timeval ctv;
    gettimeofday(&ctv,NULL);

    if( (ctv.tv_usec &gt;= tv.tv_usec) || (ctv.tv_sec &gt; tv.tv_sec) )
    {
        gettimeofday(&tv,NULL);
        tv.tv_usec+=usec;
        return 1;
    }
    else
        return 0;
}

P.S. The code must be compile in c++, I uses reference which it is not available in c. You can compile the code with g++ ,

g++ -o mytimer{,.cc}

More examples of gcc/g++ compiler shows here.

Feel free to enhance it, I appreciate any comments regarding modifications, suggestions on how to improve it.

17 thoughts on “create a timer

  1. I think this is blocking call,
    create_timer will send the signal on time elapse and on receiving signal user can take the action and meantime process other things
    This is what you are trying to achieve?

  2. something like that, but it do not deal with signal, it just let it passes if it is not his time to execute. The CheckTimer only works in the infinite loop, I use it to deal with animations or periodically live updates or in certain infinite loop thread.

  3. your progrem is good!

    I make a progrem like this, but modify a little, look ……

    /* main.c */
    /* C routine: sample gettimeofday with time in milliseconds
    mmc mchirico@users.sourceforge.net

    Downloads:
    http://prdownloads.sourceforge.net/cpearls/date_calc.tar.gz?download
    Quote: http://cc.byexamples.com/20070314/create-a-timer/
    */
    #include
    #include
    #include
    #include
    #include

    const long TIMER_5_SECONDS = 1;

    int SetTimer(struct timeval &tv, time_t sec)
    {
    gettimeofday(&tv, NULL);
    tv.tv_sec += sec;
    return 1;
    }

    int CheckTimer(struct timeval &tv, time_t sec)
    {
    char buffer[30];
    struct timeval ctv;
    gettimeofday(&ctv, NULL);

    if ( (ctv.tv_sec * 1000000 + ctv.tv_usec) >= ((tv.tv_sec + sec) * 1000000 + tv.tv_usec) )
    {
    gettimeofday(&tv, NULL);
    //tv.tv_sec += sec;
    //%m-%d-%Y
    strftime(buffer,30,”%Y-%m-%d %T.”,localtime(&(tv.tv_sec)));
    fprintf(stderr, “%s%ld\n”,buffer,tv.tv_usec);
    return 1;
    }
    else
    { return 0;
    }
    }

    void test_1()
    {
    struct timeval tv;
    SetTimer(tv, TIMER_5_SECONDS);
    fprintf(stderr, “start counting.\n”);
    while (1)
    {
    if ( 1 == CheckTimer(tv, TIMER_5_SECONDS) )
    { fprintf(stderr, “Welcome to ……\n”);
    }
    }
    }

    int main(void)
    {
    test_1();

    return 0;
    }

    ###end

    Welcome to mail me: txwcan999@gmail.com

  4. the code is good; I’ve found a lot of similar examples on the net but no one indipendent by the current time/date. For example, in my application, timer run for a lot of time (hours or days) and in the meaning time it is appened that someone has changed the time of the system causing the timer to show an erroneous count (the same automatic legal/solar date change cause the problem).
    Can you show an example on how obtain a timer base on system tick count intead on date/time?
    thanks

  5. Note: this program is not yet done…………

    int xtime_make(struct xtime *xtp,
    const struct tm *tmptr,
    const timezone_t *tz)
    {
    if (tz == NULL) {
    if (tmptr->tm_sec tm_sec > 60 ||
    tmptr->tm_min tm_min > 59 ||
    tmptr->tm_hour tm_hour > 23 ||
    tmptr->tm_mon tm_mon > 11 ||
    tmptr->tm_mday tm_mday > … ||
    tmptr->tm_isdst > 0)
    {
    int mon = tmptr->tm_mon – 1;
    int year = tmptr->tm_year + 1900;
    int sec = tmptr->tm_sec;

    if (!xtp) return 0;

    if (mon nsec = 1_000_000_000;
    sec = 59;
    } else
    xtp->nsec = 0;
    xtp->sec = ((((int_fast64_t) (year/4 – year/100 + year/400 +
    367*mon/12 + tmptr->tm_mday) +
    year*365 – 719499) * 24 +
    tmptr->tm_hour) * 60 +
    tmptr->tm_min) * 60 +
    sec;
    // … check for negative years …
    }
    }
    } else {
    // handle other timezones
    // …
    }
    }

  6. I think (at least) the usec timer doesn’t work properly.

    If you increment tv_usec and make it pass the “second mark” (= 1 000 000 us) it won’t increment tv_sec and reset the tv_usec below the “second mark”.

    So, if you’re at 1s099ms and you set a 6000us timer it stops at 2s000ms when it should stop at 2s005ms. So basically it won’t work for timers longer than 1sec or if the timer ends in the next second.

  7. this is my increment function to replace “tv->tv_usec += usec”:
    void incrementTimeval(struct timeval *tv, int usec)
    {
    tv->tv_usec += usec;
    if(tv->tv_usec >= 1000000)
    {
    tv->tv_sec += tv->tv_usec / 1000000;
    tv->tv_usec = tv->tv_usec % 1000000;
    }
    }

    And my “if” has this condition:
    ( (ctv.tv_sec >= tv->tv_sec) && (ctv.tv_usec >= tv->tv_usec) )

    Here’s the full code:
    http://vudu.pastebin.com/m9e9404a

  8. Hi,
    This is DAS ,In these examples i get how to allocate a delay to the process get it. But i did’t get in that delay how to run another task (execution of another process). Can i get any example programs in to my mail ID

  9. mysurface: while it might be true that “because the programs suppose to process for other things within this 5 seconds” is of concern, the example given here still is VERY problematic since it’s a busy loop.

    If one needs background processing while waiting, then one would do much better by using a proper multi-event capable select() mechanism in the app.
    If one needs such handling, then this is the way to go.
    If one for some reason doesn’t want to use a select()-based mechanism, then launch one or more worker threads.
    But simply burning CPU for CPU upgrading’s sake (the infamous Wintel behaviour) is a no-no.

  10. it’s a blocking call… the timer should be in a different thread.
    no example that was given is good .

  11. Thanks for your code and i am implementing a scheduler with the same code , but in this code you have used a while(1) loop for continious checking that is creating a performence issue for me. so how can i over come that please help me in this issue.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>