Dear Sqr,
I want to print the time to be delay by 5 seconds from the current time so I tried this but it does not work and keep showing me 1970-01-01 07:30:00
strftime(buff, 20, "%Y-%m-%d %H:%M:%S", localtime(&tv.tv_sec - 5));

I'm not sure why you are trying to modify the time...

However, that aside, you can not subtract from the memory address as you are attempting to do. What you might try is something along the lines of:

tv.tv_sec -= 5;
strftime(buff, 20, "%Y-%m-%d %H:%M:%S", localtime(&tv.tv_sec));

Dear Sqr,
Thank you if I would like to print both the original time and the minus time is that possible?

Dear Sqr,
Thank you if I would like to print both the original time and the minus time is that possible?

Sure, print the time before you subtract the 5 seconds; then subtract the 5 seconds; then print the time again.

Dear Sqr,
        I have been running the codes above it start of with very little memory usage and later ends up with huge usage. I am confuse why when there is just one thread and huge memory usage.

It is hard to tell from the examples that have been presented here. My guess is that there is some resource you are not freeing during each iteration (a memory leak). It may be related to the query code if you are not calling malloc in your code.
How are you connecting to the database? Do you have a complete example we can look at?

Dear Sqr,
         Below is part of the full codes.





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


int flag = 0;

MYSQL *localConn, *remoteConn;
MYSQL_RES *localRes1, *remoteRes1;
MYSQL_RES *localRes2, *remoteRes2;
MYSQL_ROW localRow1,remoteRow1 ;
MYSQL_ROW localRow2,remoteRow2 ;

void * reader_thread (void * arg) {
    while (1) {
        if (flag) {
            struct timeval tv;
            char timeBuf[10], queryBuf1[500],queryBuf2[500];
            char buff[20] = {0};
            gettimeofday (&tv, NULL);
            //fprintf (stderr, "[%d.%06d] Flag set to 1 on ", tv.tv_sec, tv.tv_usec);
            tv.tv_sec -= 5;
            strftime(buff, 20, "%Y-%m-%d %H:%M:%S", localtime(&tv.tv_sec));
            printf("\nTime is %s", buff);




            /* Connect to database */


           sprintf(queryBuf1,"SELECT ipDest, SUM(packetLen), COUNT(ipDest) FROM packDb1 WHERE timeStamp = '%s' GROUP BY portDest",buff);
                //printf("\nQuery buf %s",queryBuf1);
                if(mysql_query(localConn, queryBuf1))
                {
                    fprintf(stderr, "%s\n", mysql_error(localConn));
                    exit(1);
                }

                localRes1 = mysql_store_result(localConn);

                //output table name
                //printf("Mysql Tables in mysql database: \n");
                while((localRow1 = mysql_fetch_row(localRes1)) !=NULL)
                {
                  printf("RECEIVE %s,%s\n", localRow1[0], localRow1[1]);
                  sprintf(queryBuf1,"INSERT INTO  packets.packRec (iBTID ,timeStampID ,ipDest ,totalBits, packetCount) VALUES (NULL,'%s','%s','%s','%s')",buff, localRow1[0],localRow1[1],localRow1[2]);
                  printf("%s\n",queryBuf1);
                  if (mysql_query(localConn, queryBuf1)) 
                  {
                     fprintf(stderr, "%s\n", mysql_error(localConn));
                     exit(1);
                  }

                }



                }
               /* close connection */
               //mysql_free_result(localRes);
               //mysql_close(localConn);




            fprintf (stderr, " %s\n", buff);
            flag = 0;
        }
        usleep  (100); // 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;
    char *localServer = "localhost", *remoteServer = "localhost";
                       char *localUser = "user1", *remoteUser = "user2";
                       char *localPassword = "****", *remotePassword = "*****";
                       char *localDatabase = "db1", *remoteDatabase = "db1";
                       localConn = mysql_init(NULL), remoteConn = mysql_init(NULL);
    if (!mysql_real_connect(localConn, localServer,
                         localUser, localPassword, localDatabase, 0, NULL, 0)) {
                      fprintf(stderr, "%s\n", mysql_error(localConn));
                      exit(1);
                   }   

                   if (!mysql_real_connect(remoteConn, remoteServer,
                         remoteUser, remotePassword, remoteDatabase, 0, NULL, 0)) {
                      fprintf(stderr, "%s\n", mysql_error(remoteConn));
                      exit(1);
                   }

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

The problem seems to be a result of the following line

localRes1 = mysql_store_result(localConn);

You never call mysql_free_result which leads to a memory leak. See this link for details.

Dear Sqr,
         Thank you it works fine now. 

Who is Sqr? And why are all your posts in Code Tags?

Dear Waltp,

I am having problem to post. Whenever I post it shows me this message "The code snippet in your post is formatted incorrectly. Please use the Code button in the editor toolbar when posting whitespace-sensitive text or curly braces" eventhough it is not a code. So why is this ya?

Whitespace and curly braces are used to determine whether or not you're likely to be posting code. After "Dear XYZ", you type a bunch of spaces on the next line as if you're composing a letter, which due to the indentation is error checked as code.

Any code block must be preceded by either nothing (ie. the beginning of the post) or a blank line to be highlighted properly, so we disallow any indented line immediately preceded by an unindented line.

Short answer: you're not writing a letter, so don't format your post as such. Even if you separated "Dear XYZ," with a blank line, the rest of your post would be formatted as code, which is difficult to read. So unless you intend to create a code block, please start all of your lines at column 0.

L7Sqr,I have one new problem now I notice that my script is not running exactly on every second any more. Could it be due to the nature that the queries are taking time to process and that is where there is a skip of the every second?

If you mean a script that runs on MS-Windows or *nix? Those are not real time operating systems, so there is no way to schedule someting to run at exactly the same time, such as exactly at 1 minute intervals. If you need that kind of accuracy then you will have to get a different operating system. You might find that task scheduling is more accurate on multi-core computers.

If you look at the example I gave in the beginning of the thread (here) I mentioned that it would not be exact. The problem with checking for a flag is that if your processing (in the thread) takes as long as or longer than your delay then you are going to miss an update every so often. There are ways to mitigate this further (instead of processing in the thead you can fork or create another thread) but as the example stands your processing has an effect on the ability to receive updates.

So can I fork another thread from the existing thread and do the processing there? So what is the best way to call another thread keep creating a new pthread is it? I would like to know the best method as I am worried ending up in eating the memory?

Dear L7Sqr,Below is my latest codes where I call separate thread for the query processing. But the problem is still the same the seconds do jump too.

typedef struct str_thdata
{
    int thread_no;
    char message[100];
} thdata;               

void print_message_function ( void *ptr )
{
    char secondBuf1[100],queryBuf1[500],queryBuf2[500];
    thdata *data;            
    data = (thdata *) ptr;  /* type cast to a pointer to thdata */

    /* runAllTheQueries here */


    pthread_exit(0); 
}       
void * reader_thread (void * arg) {
    while (1) {
        if (flag) {
            struct timeval tv;
            char timeBuf[10];
            char buff[20] = {0};
            gettimeofday (&tv, NULL);
            //fprintf (stderr, "[%d.%06d] Flag set to 1 on ", tv.tv_sec, tv.tv_usec);
            tv.tv_sec -= 5;
            strftime(buff, 20, "%Y-%m-%d %H:%M:%S", localtime(&tv.tv_sec));
            printf("\nTime is %s", buff);

           pthread_t thread1, thread2;  /* thread variables */
            thdata data1, data2;         /* structs to be passed to threads */

           data1.thread_no = 1;
           strcpy(data1.message, buff);

           pthread_create (&thread1, NULL, (void *) &print_message_function, (void *) &data1);
           pthread_join(thread1, NULL);  

            fprintf (stderr, " %s\n", buff);
            flag = 0;
        }
        usleep  (100); // will skew the processing but not signal delivery
    }
    return NULL;
}

When you call pthread_join you block the current thread until the one you want to join with finishes. It's basically the same as executing the code in the original thread. I would suggest that instead of spawing a thread to do the processing that you fork another process. Something like (pseudocode):

while (1) {
   if (flag) {
      // ... some code here
      if (fork() == child) {
         do queries here in a seperate process
      } else { 
         // this is the parent
         usleep (100);
      }
   }
}

This will require that you set up some IPC if you want to communicate what is happening with the queries and it cant be self-contained. Alternatively, you can just not call pthread_join after you spawn the thread.

There is a lot of options to consider in the above scenarios (are there shared resources, what happens if two queries run at the same time, ...) and only you can make the decision based on these factors.

Dear L7Sqr, I got error here if (fork() == child). I replace it with this if(fork()) it works and is this right? But then it will never stop right because I tried control + Z it does not stop all.

DEar L7sqr, The code run but it spawns a lot of child process and after some time it halt maybe due to heavy memory usage is it?

The code I provided was pseudocode - not meant to be syntatically correct. Also, when you fork a child process to run a specific task you will want to call exit when you are done in that process. The general case is (again, pseudocode):

if (fork() == child) {
   // do processing here
   // exit when done processing
   exit(0);
} else {
   // continue with parent execution
}

Where should the flag=0 be inserted in the if or else part? and another thing I notice is that when I put the exit(0) and flag=0 before the fork it only run once. If I put the flag=0 just before exit(0) in the if of the fork it keep repeating many a times the same time.

I think you should step back for a moment and digest the situation a bit instead of just trying to copy the code you get at each step into someplace in your existing code.
The original logic of your code is as follows:

  • you check for a flag repeatedly within a thread.
  • When this flag is true, you execute code within that thread of execution

The problem, as you found, is that any query executed from within that thread that lasts longer than the interval of your timer will prevent you from receiving the next signal. The suggested fix is to fork a child process to handle the query allowing the thread that handles the monitoring of the flag to avoid blocking on the database interactions.

I think you should consider the best place to make that change - essentially what you want is to encapsulate the query bahavior in a child process. This can happen in the timer callback or a thread monitoring a flag (your current implementation).

If you dont understand what is happening and what changes you are making you will only create a more tangled situation the next time you need to debug.

Dear L7Sqr, I was just trying out so what I did now is print the timer value in the void callback function and it is printing the time accordingly. I also have tried to run my queries in it too but due the time difference of one select to another select is too fast I get mysql error on command out of sync. I think I know the problem is that while one select is running and pumping data into the insert immediately next select starts. Is there any work around for this using C?

It sounds like, at this point, the error is in the logic of how you interact with the database. If your queries take longer than one second and can not run concurrently then you should not be trying to execute them at a one-second interval.

Where does the one second requirement come from? Is it flexible? Is there an ability to optimize the query a bit for better performance? These are questions that are germane to your situation but hard to answer without detailed input.

@L7Sqr, Actually we are just running a select and insert but as you said is more on logic because at times it runs well when the traffic is not heavy and when the traffic is heavy things get into error. The problem is no flexibility to go more then 1 second.

@L7Sqr I have come out with another solution within thread callback I am trying to create new threads to do the db processing it works but at times some seconds goes missing and not process too. Below is the snippet of codes. I have been adjusting the position for the flag=1 but still is not working out.

void * reader_thread (void * arg) {
    while (1) {
        if (flag) {

            flag = 0;
        }
        usleep  (100); // will skew the processing but not signal delivery
    }
    return NULL;
}



void callback (int sig) {

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

            //printf("\nSeconds Value is %d",ts->tm_sec);

    pthread_t tid; 
    pthread_create(&tid,NULL,runner,buff);     
    pthread_join(tid,NULL); 

}

void *runner(void *param)
{
  char *buff = (char*)param;   

  printf("\nPrint thread %s",buff);

  MYSQL *localConn1a,*localConn1b;


  MYSQL_RES *localRes1; 
  MYSQL_ROW localRow1;


               char *localServer = "localhost";
                       char *localUser = "root";
                       char *localPassword = "pass1";
                       char *localDatabase = "db1";
                       localConn1a = mysql_init(NULL);
                       localConn1b = mysql_init(NULL);

    if (!mysql_real_connect(localConn1a, localServer,
                         localUser, localPassword, localDatabase, 0, NULL, 0)) {
                      fprintf(stderr, "%s\n", mysql_error(localConn1a));
                      exit(1);
                   } 
      if (!mysql_real_connect(localConn1b, localServer,
                         localUser, localPassword, localDatabase, 0, NULL, 0)) {
                      fprintf(stderr, "%s\n", mysql_error(localConn1b));
                      exit(1);
                   } 


    //db processing here


                mysql_free_result(localRes1);

                mysql_close(localConn1a);
                mysql_close(localConn1b);

  pthread_exit(0);
}
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.