LinuxQuestions.org
Review your favorite Linux distribution.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 01-07-2012, 07:16 PM   #1
newbie14
Member
 
Registered: Sep 2011
Posts: 646

Rep: Reputation: Disabled
C timer_create skeleton


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.


Code:
#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;
value.it_value.tv_nsec = 0;

value.it_interval.tv_sec = 1;
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);
}
 
Old 01-07-2012, 07:41 PM   #2
RudyMartin
Member
 
Registered: Nov 2011
Location: Argentina
Distribution: Slackware, Debian
Posts: 38

Rep: Reputation: Disabled
why not a select() call with 1 delay second inside a loop?

I have faced a problem similar to yours some ten years ago, ended up using select but I don't have the code at hand to post it.
 
Old 01-07-2012, 07:49 PM   #3
newbie14
Member
 
Registered: Sep 2011
Posts: 646

Original Poster
Rep: Reputation: Disabled
Dear Rudy,
I heard that time_create is the latest api for C so that is why I am testing it. Maybe that can help us.
 
Old 01-08-2012, 11:05 AM   #4
RudyMartin
Member
 
Registered: Nov 2011
Location: Argentina
Distribution: Slackware, Debian
Posts: 38

Rep: Reputation: Disabled
Quote:
Originally Posted by newbie14 View Post
Dear Rudy,
I heard that time_create is the latest api for C so that is why I am testing it. Maybe that can help us.
no offense intended but you might heard wrong as well. part of your code can be used on a select function. just give it a try.

info select
info pthreads
 
Old 01-09-2012, 03:10 AM   #5
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,862
Blog Entries: 1

Rep: Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869
Note: 'Latest standard' is a synonym for 'unimplemented yet'.
 
Old 01-09-2012, 04:53 AM   #6
Nominal Animal
Senior Member
 
Registered: Dec 2010
Location: Finland
Distribution: Xubuntu, CentOS, LFS
Posts: 1,723
Blog Entries: 3

Rep: Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948
Quote:
Originally Posted by NevemTeve View Post
Note: 'Latest standard' is a synonym for 'unimplemented yet'.
Huh? timer_create(), timer_delete(), timer_getoverrun(), timer_gettime(), and timer_settime() are specified in POSIX.1-2001, and are fully implemented in GNU libc 2.3.3 and later, and Linux kernels 2.6.12 and later. Earlier kernels lack per-process and per-thread clocks, and earlier libc versions have incompatible timer_t on 64-bit arches, I believe. These functions most definitely are already implemented.

timer_create() is the recommended interface for POSIX signal-based interval timers. (One can either rely on getting a blocked call interrupted by the signal delivery, or post a semaphore in the signal handler. If unsure, check man 7 signal, specifically Async-signal-safe functions section to see which library functions can be used in a signal handler.)

However, I agree with RudyMartin that in newbie14's case, a delay-based loop is the recommended and most practical solution for this.

I personally would prefer to use nanosleep() (another POSIX.1-2001 function) for the wait, and timer_gettime(CLOCK_REALTIME,...) if necessary to monitor the elapsed time during the SQL query and response processing, if there is a preferred interval to keep to, or if the query rate needs to be accurately measured in wall clock time. Note that I don't use Windows, ever, so I don't know (or indeed care, at all), if such code compiles or runs on Windows. I do know that such code works very well in Linux, though. (Just remember to use #define _POSIX_C_SOURCE 199303L or later -- I prefer 200809L -- to tell the C library you wish to use these POSIX interfaces.)

(My memory is hazy, but I seem to recall some issue with select() timeouts.. Ah yes, according to man 2 select only Linux updates the timeout (to account for the elapsed time). This means that you cannot in general rely on the updated timeout value to reflect the amount of time spent waiting in the select() call; that will only work in Linux. I seem to also recall some race conditions when the timeout is not updated, but I cannot find a reference -- I might remember wrong. The nanosleep() interface on the other hand does not interfere with signals, specifically SIGALRM signal, at all; and the unslept time is always returned, even if the sleep was interrupted by signal delivery.)
 
Old 01-09-2012, 06:25 AM   #7
newbie14
Member
 
Registered: Sep 2011
Posts: 646

Original Poster
Rep: Reputation: Disabled
Dear All,
I guess you guys are very senior in this field. 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.
 
Old 01-09-2012, 12:22 PM   #8
RudyMartin
Member
 
Registered: Nov 2011
Location: Argentina
Distribution: Slackware, Debian
Posts: 38

Rep: Reputation: Disabled
Quote:
Originally Posted by newbie14 View Post
Dear All,
I guess you guys are very senior in this field. 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.
@newbie14

I was about to say something like nominalanimal said but since I'm new to this forum I don't want to sound rude in any way.

from the look of how to present your problem so far, two things are becoming clear to me.

1) you don't seem to be a programmer. Internet and forums were up an running more than ten years ago, and when I faced a problem similar like yours I kept writing tests to understand how to solve it until I was able to write a decent code. That's how I ended up using select and pthreads. And I had to do it for months. If you are not a programmer and you are in a hurry, you should hire one.

2) I fail to see clearly the real problem to solve (real world I mean, not a mathematics's toy case). If I were you I would start all over stating the problem and what have you investigated so far besides the code you posted.

http://catb.org/~esr/faqs/smart-questions.html

again, no pun intended.
 
Old 01-09-2012, 07:31 PM   #9
Nominal Animal
Senior Member
 
Registered: Dec 2010
Location: Finland
Distribution: Xubuntu, CentOS, LFS
Posts: 1,723
Blog Entries: 3

Rep: Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948
Quote:
Originally Posted by RudyMartin View Post
I was about to say something like nominalanimal said but since I'm new to this forum I don't want to sound rude in any way.
Sorry about that. I did not intend to be rude; I was genuinely puzzled. If I offended anyone, I want to apologize.

Quote:
Originally Posted by RudyMartin View Post
2) I fail to see clearly the real problem to solve (real world I mean, not a mathematics's toy case). If I were you I would start all over stating the problem and what have you investigated so far besides the code you posted.
I whole-heartedly agree. newbie14, could you please start a new thread, and explain the problem you are trying to solve? Additional information, like approaches you have already considered, and technical or organizational limitations, are very important, too. Most likely there are a number of different solutions.

In the past year, in threads I've participated in, usually a few different approaches are first suggested, and then the OP or discussers pick one that seems to suit the situation best. The important thing is that different people have different experiences, and combining all that is likely to give a fuller picture than just listening to a single expert. I've programmed both proprietary and open source software for two decades now, and I still learn new things when discussing different approaches to problems here. Every time. I've learned to not rely on length of experience, but the variety. And that is what LQ can provide for you, if you can just pose an interesting enough problem.

As a practical example, let me describe you a pretty esoteric way to monitor the progress of a process. I don't really think it is a suitable solution for this problem, but it is very simple to implement, quite robust, and not something most programmers would think of.

First, in your process to be monitored, you use compiler-provided atomic built-ins to update the integer value that is monitored. (The ones I prefer to use due to their widespread support are the __sync variety; however, the latest C and C++ include __atomic ones, which will become very widely supported in the next couple of years.) In short:
Code:
/* Global variable(s) -- here, an array of five values.
 * Note that the C standard says that {0} initializes any
 * array, regardless of types, to all zero bits. */
#define MONITORED_VALUES 5
static volatile long monitored_value[MONITORED_VALUES] = { 0 };

/* How to atomically increment it */
__sync_add_and_fetch(&monitored_value[N], (long)increase_by_amount);
This works even if you have multiple threads modifying the value at the same time. No locks are needed. Second, you pick a realtime signal number -- realtime signals are queued, so you don't lose one even if you happen to get more than one at the same time --, and set a very simple handler to it: When it receives a signal, it responds to the sender with the same signal, but with the monitored value as a payload. Since there is only one integer per signal, the incoming signal will specify the variable (as an index, for example). Note that I'm using the long type, since in Linux, pointers and long are always the same length (all Linuxes are either ILP32 or LP64).

The sigaction-type signal handler is rather simple:
Code:
#include <signal.h>
#include <errno.h>

void signal_responder(int signum, siginfo_t *info, void *data)
{
    const long index = (long)data;
    if (index >= 0L && index < MONITORED_VALUES) {
        union sigval response;
        response.sival_ptr = (void *)__sync_or_and_fetch(&monitored_value[index], 0L);
        sigqueue(info->si_pid, signum, response);
    }
}

/* Signal handler installer */
int install_signal_responder(const int rtsignum)
{
    struct sigaction  act;

    sigemptyset(&act.sa_mask);
    act.sa_sigaction = signal_responder;
    act.sa_flags = SA_RESTART | SA_SIGINFO;
    if (sigaction(SIGRTMIN + rtsignum, &act, NULL) == -1)
        return errno;

    return 0;
}
Of course, in the program you must then remember that any blocking call (listed in man 7 signal, Interruption of System Calls ... section), can return -1 with errno set to EINTR, if the signal delivery interrupts the blocking call. This is most important with read()/write() calls, but affects a number of other library functions too.

Any process that can send signals to that process can then monitor the designated integer values simply by setting a corresponding signal handler (to catch the value in the data pointer), and using sigqueue() in similar fashion as above. (If you want to do it carefully, it takes a bit more code than above, but it's pretty straightforward. The main issue is to take into consideration that the target process might not answer, or that you might get a spurious belated answer when not expecting one.)

Like I said, the above is quite esoteric. I'm not sure if there is any situation where it might be the preferred one -- perhaps on some embedded architecture with very expensive threads (in computing terms).

The most versatile version I can think of is to have a named pipe (usually /var/run/programname.state or similar), and a separate thread in a loop. In the loop, the thread will open the named pipe, constructs the current state as a short text messge (< 512 characters), writes it into the pipe using a single syscall, then closes the named pipe. The open will block until a reader opens the pipe. This way, you can read the named pipe from any other process easily, just as if it was a plain text file -- even using things like state=$(cat /var/run/programname.state) in Bash -- to retrieve the progress. (Having Unix time as part of the response is very useful when measuring the progress.)

While this approach requires minimal thread support (linking against pthreads), it does not limit the main program any more than the signal approach. You should still use atomic built-ins to update the integers monitored. In the looping thread, you'd best use snprintf(), but if you want to do it the hard way, you can construct the buffer backwards using minimal but extremely efficient code (for integer values and strings only, though).

Again, this named pipe thing is just the most versatile. I'm sure that there are a large number of monitoring problems where there are much better alternatives. The problem is, we have no idea what your original problem you're trying to solve really is, so anything we might suggest is most likely suboptimal.
 
Old 01-09-2012, 08:22 PM   #10
newbie14
Member
 
Registered: Sep 2011
Posts: 646

Original Poster
Rep: Reputation: Disabled
Dear Nominal,
I am looking into you solution.Well I guess I got a lot to learn from you as you seem to have a lot of experience. Anyway as per your suggestion I will start a new thread with full description. Sorry for the time here.
 
Old 01-09-2012, 11:09 PM   #11
Nominal Animal
Senior Member
 
Registered: Dec 2010
Location: Finland
Distribution: Xubuntu, CentOS, LFS
Posts: 1,723
Blog Entries: 3

Rep: Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948
Quote:
Originally Posted by newbie14 View Post
Anyway as per your suggestion I will start a new thread with full description. Sorry for the time here.
No need to be sorry for anything!

When describing a problem, try to tell us what are the most important things you wish to accomplish. For example, if there are multiple users who regularly observe the output, do not assume that a web page is the best solution; tell us that there are multiple users who regularly need to observe the output instead, and that you consider a web page a good option. Even if your initial question does not hit the mark exactly, that too is okay: you can always amend and clarify your questions. Just like now, if you "restart" by posing the original problem, instead of asking just a technical programming question.

Good luck!
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
timer_create failing manohar Programming 3 06-21-2011 12:18 PM
usb-skeleton.c help??? Penguin01 Linux - Kernel 1 12-15-2009 07:47 PM
[C/C++] Using timer_create() and interrupting sleep() dwhitney67 Programming 0 05-19-2009 07:30 AM
Timer Deadlock problem in timer_create and delete_timer nkk4u Programming 0 04-15-2005 02:10 AM
Skeleton directories for new users? jungatheart Linux - Newbie 2 04-24-2004 03:44 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 06:03 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration