Dear All,
My problem is that exactly every second I need to call a particular function to do some sql querying. So after reading I found that the latest api is timer_create. Below is a skeleton. Is this skeleton a right one to move forward? Thank you.

#include <stdio.h>
#include <time.h>
#include <signal.h>

timer_t gTimerid;

void start_timer(void)
{


struct itimerspec value;

value.it_value.tv_sec = 1;//waits for 5 seconds before sending timer signal
value.it_value.tv_nsec = 0;

value.it_interval.tv_sec = 1;//sends timer signal every 5 seconds
value.it_interval.tv_nsec = 0;

timer_create (CLOCK_REALTIME, NULL, &gTimerid);

timer_settime (gTimerid, 0, &value, NULL);

}

void stop_timer(void)
{


struct itimerspec value;

value.it_value.tv_sec = 0;
value.it_value.tv_nsec = 0;

value.it_interval.tv_sec = 0;
value.it_interval.tv_nsec = 0;

timer_settime (gTimerid, 0, &value, NULL);


}


void timer_callback(int sig) {

 printf(" Catched timer signal: %d ... !!\n", sig);
 
}

int main(int ac, char **av)
{
    (void) signal(SIGALRM, timer_callback);
    start_timer();
    while(1);
}

Recommended Answers

All 56 Replies

>>exactly every second I need to call a particular function

Neither MS-Windows nor *nix is that accurate, actual time may be +/- a few milliseconds, depending on what else the operating systems and other processes are doing.

Dear Dragon,
I dont mind the few milisecond but at least it can show the very second will do.

I'm not a *nix programmer, so someone else will have to answer your question.

The problem with signal is that there's not much you can do in a handler. The list of signal-safe functions is quite limited (man 7 signal), and printf is not one of them. I don't know what exactly your sql querying involves, but the gut feeling says that signal handler is not a right place.

Dear Neza,
What is your best recommendation then so overcome my problem here?

You mention an exact requirement, then relax that to allow for a variable amount of delay. How critical is this timer? Are you sure you aren't just interested in having a query execute every second or so?

If so the timer you set up will allow for that. However, how long do you expect the query to take? The callback is blocking - how will you receive the next signal if you exceed the 1 second mark? If you expect to do other processing and the process of signals, queries, and callbacks take too much time you will spend the majority of execution cycles on just the timer mechanism.

If the time is not exactly critical why not just issue a signal(1) after you finish each query? If the query will be blocking and take a long time perhaps a second thread caould handle the DB interaction while the main thread does what it is currently doing.

Dear Sqr,
Let me let you give you more details on why I need to call it on per second basis. In the background I have data entering at a very high rate few thousand per second. So then I want to call another service(which is this one) on per second basis to summarize the total data received on per second. Hope I am clearer now.

In that case, I'd suggest you use a separate thread that will handle the database interaction while the main thread does similar to what you have above. The exception is that in the callback you simply set a variable to be read in the database thread instead of doing any work in the main thread.

All of the points I've made above about overlapping times and long delay on database queries still stand. You will need to be aware of them and take precautions that none of them affect the way you are handling the signals.

Dear Sqr,
I would like to ask can I just run all my sql statement in the timer_callback function what is the risk? You ask me to start another thread right is that possible via C? Any sample on how to do it?

If the callback is blocking (it suspends the calling context until it completes) and the time to run the query is unknown and greater than 0 then you are affecting your timer resolution on every call - possibly for longer than the timer interval itself.

Consider the following scenario:

callback code:
   send SQL query (may take a full second to process)
   process results
   return

main code:
   set timer

Which may result in the following sequence of events:

timer scheduled [time 0.0000, drift 0.0000]
enter callback @ time 0.0000
   query [takes 0.01 seconds]
   processing [takes 0.01 seconds]
   return
timer rescheduled [time 0.02, drift 0.02]
enter callback @ time 1.0200
   query [takes 1.3 seconds]
   processing [takes 0.01 seconds]
   return
timer rescheduled [time 2.32, drift 1.33]

So you can see you can end up skipping an entire timer interval or introducing an ever increasing amount of drift into your timer if you do it in a blocking call. In the [exaggerated] example above the drift is 1.33 seconds over 2.32 seconds of execution!

Dear Sqr,
How to know if my callback is blocking or not? I get your idea meaning that at every 1 sec spawn a new separate thread and do the sql processing in that am I correct here? I am new to C thread is it called thread_t?

Your callback is blocking. You need to spend as little time as necessary in that block of code.

As for my suggestion of threads, I would go with only a single thread that waits for messages from the main thread (sent from the callback). I would use pthreads.

Dear Sqr,
It is a good link cause all this while I was thinking fork is good solution but after reading it looks like pthread is better. Ok I saw an example of this sort. So in my case I have to call the thread in the blocking function. It requires to set number of thread but how to set in my case it will per second?

pthread_t threads[NUM_THREADS];
   int rc;
   long t;
   for(t=0; t<NUM_THREADS; t++){
      printf("In main: creating thread %ld\n", t);
      rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t);
      if (rc){
         printf("ERROR; return code from pthread_create() is %d\n", rc);
         exit(-1);
      }
   }

I am suggesting that you have only 2 threads: 1 for the main execution, 1 to do the queries. Below I give an example program with all error checking, mutex locking and other safety procedures removed for clarity.

#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <stdio.h>
#include <time.h>
#include <signal.h>

int flag = 0;

void * reader_thread (void * arg) {
    while (1) {
        if (flag) {
            struct timeval tv;
            gettimeofday (&tv, NULL);
            fprintf (stderr, "[%d.%06d] Flag set to 1\n",
                    tv.tv_sec, tv.tv_usec);
            flag = 0;
        }
        usleep  (1000); // will skew the processing but not signal delivery
    }
    return NULL;
}

void callback (int sig) {
    flag = 1; // this is the only thing the callback does
}

int main () {
    timer_t tid = 0;
    pthread_t thread;
    struct itimerspec it;

    pthread_create (&thread, NULL, reader_thread, NULL);

    signal (SIGALRM, callback);

    it.it_value.tv_sec = 1;
    it.it_value.tv_nsec = 0;
    it.it_interval.tv_sec = 1;
    it.it_interval.tv_nsec = 0;
    timer_create (CLOCK_REALTIME, NULL, &tid);
    timer_settime (tid, 0, &it, NULL);

    while (1) sleep (100);
    return 0;
}

When I run that I get the following:

[1326198418.496489] Flag set to 1
[1326198419.498436] Flag set to 1
[1326198420.500408] Flag set to 1
[1326198421.499364] Flag set to 1
[1326198422.501326] Flag set to 1
[1326198423.503288] Flag set to 1
[1326198424.505252] Flag set to 1
[1326198425.504216] Flag set to 1
[1326198426.507177] Flag set to 1
[1326198427.506141] Flag set to 1
[1326198428.509102] Flag set to 1
[1326198429.509067] Flag set to 1
[1326198430.511030] Flag set to 1
[1326198431.510993] Flag set to 1

Notice that there is still some drift in there. Without a RTOS you are going to have to allow for that but there are ways to try and get even tighter bounds on it such as timer_getoverrun .

Dear Sqr,
Let grab something slowly as I am new to this. Correct me pthread_create will just create one thread rite.So how will the rest of the threads get created? Why do we put this signal (SIGALRM, callback); before the call of the time_create and what is the need for the while (1) sleep (100);? Sorry ya I want to learn so I want to know what I am doing in detail.

pthread_create will just create one thread rite.

Yes

So how will the rest of the threads get created?

There is no need for more than that. My example has continuous output with only the one extra thread

Why do we put this signal (SIGALRM, callback); before the call of the time_create

So that we are registered for the signal before we request to have it sent

and what is the need for the while (1) sleep (100);? Sorry ya I want to learn so I want to know what I am doing in detail.

On my system, if I do not insert a sleep there the main thread exits before the first signal is delivered.

Dear Sqr,
Ok I am getting clearer. Another thing I want to get things clear is this signal fundamentally what is its job to send interruption like here SIGALARM will send interruption and call the callback function. But in this case where does the SIGALARM comes from? So which is the one which exactly call at the very second?

Signals are asynchronous events delivered to your program. Each of them have a default action associated with them which you can change by registering a user-defined callback. This is what you've done with the call to signal (SIGALRM, callback); Now, every time the SIGALRM signal is delivered to your program the function callback is invoked instead of the default handler.

As for how that signal is delivered, well that is the whole point of the timer_settime call. You are requesting that a signal be sent to your program at a particular interval - in this case you request the default signal but you could request any signal you like when you call timer_create

Dear Sqr,
I am getting it better now so in the beginning we already create a new thread. Timer_create is call is just like a clock instance and there you set the type of clock. timer_settime is where the clock start working right, but one thing I want to clear it.it_value.tv_sec = 1; and it.it_interval.tv_sec = 1;. The interval is 1 sec will it we be missing the next second or not ? Another thing I want to understand when it expire to 1 sec then it call the callback to set the flag to 1. But how will this flag=1 is pass to reader_thread which separate thread?

In my example I placed flag in the global space. This means it is accessible by each thread. An alternative is that you can pass a pointer to the variable as an argument to the thread but then you have the problem of being able to update it directly in the callback function.

Dear Sqr,
When will the reader_thread will be called actually every second is it? Is it after callback is being called then reader_thread is called. Another thing I added codes into the reader_thread which print the time is that correct what I am doing?

void * reader_thread (void * arg) {
    while (1) {
        if (flag) {
            struct timeval tv;
            gettimeofday (&tv, NULL);
            fprintf (stderr, "[%d.%06d] Flag set to 1\n",
                    tv.tv_sec, tv.tv_usec);
            char buff[20]; 
            time_t now = time(NULL); 
            strftime(buff, 20, "%Y-%m-%d %H:%M:%S", localtime(&now)); 
            printf("\nBuff : %s",buff);
            flag = 0;
        }
        usleep  (1000); // will skew the processing but not signal delivery
    }
    return NULL;
}

You can add whatever you like to the thread code since it does not interfere with the callback. I already print out the time (in seconds and microseconds) and on my system the tv_sec member variable is a time_t type so you could just do the following:

struct timeval tv;
char buff[20] = {0};
gettimeofday (&tv, NULL);
fprintf (stderr, "[%d.%06d] Flag set to 1 on ", tv.tv_sec, tv.tv_usec);
strftime(buff, 20, "%Y-%m-%d %H:%M:%S", localtime(&tv.tv_sec));
fprintf (stderr, " %s\n", buff);
// ...

In reality, though, I only put that code there to show the timer drift and how to run the thread code. You will want to put your query and reporting code there instead.

Dear Sqr,
Thank you for the current time code. One thing I am still not clear is when will the reader_thread will be called?

The code in that function is called only once at pthread_create . The system handles the setup and execution of the function that is provided as an argument to the call.
That function will continue to execute until it exits the function block, the main thread exits or it is somehow killed by another process. In no case should you call that function directly.

Dear Sqr,
Ok I got now so clear. But then you have this usleep (1000); /if I remove this will it a problem because you put to sleep every 1 second rite then how it still picks up exactly the next second?

The usleep(1000) executes in the thread function. It is simply a way to lower the impact of the thread (so you dont see 100% CPU use). I would suggest setting that sleep interval to the lowest tolerable delay you can support. If you can support 100 microsecond variations in the results then use that. If the tolerance is tighter, set it accordingly.
You could just remove it entirely but you would see a huge spike in processor usage while your program is running.

Dear Sqr,
Just wondering if I set to 1000 it will sleep one second and exactly wake up at that second right?

>>and exactly wake up at that second right?
Wrong. That is only a hint to the operating system when to wake up the thread. It will be pretty close to 1 second but may be +/- a few milliseconds.

The problem with setting the thread sleep to close to 1 second is that you are very likely to miss signals that way. You want to have the sleep set to the maximum amount of tolerable delay. No more.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.