yes but not in while(1) loop
Main Topics
Browse All TopicsThe requirement i have a function to be called at intervals of 5 seconds , I have registered SIGALRM
signal for 5 seconds and waiting with while(1); in main How to avoid while(1); so that Process Status will be show as S and when the Function is executing it should turn to R
This Question has been solved and asker verified All Experts Exchange premium technology solutions are available to subscription members.
Experts Exchange has been collecting answers to technology questions since 1996…3 million and counting! If you have a question, chances are we already have your answer.
If you can't find the exact answer you're looking for, ask our exclusive community of 50,000 experts. You’ll get a personalized answer from a trusted professional.
Thousands of free tech tips, tricks, how-to’s and tutorials are available in our peer reviewed articles section. See for yourself how smart our experts are, no login required.
Access the answers to your technology questions today.
30-day free trial. Register in 60 seconds.
Members of the expert community talk about why the experience at Experts Exchange is different than what you will find anywhere else.

Try it out and discover for yourself.
30-day free trial. Register in 60 seconds.
Join the community of experts here and help other tech pros by answering question in your area of expertise. You can earn FREE access to all Experts Exchange's premium features and resources.
The Question is very simple how to avoid while(1) in code which is using SIGALRM
like this
#include <stdio.h>
#include <signal.h>
int wakeUp() {
printf("Wake up \n");
signal(SIGALRM,wakeUp);
alarm(1);
}
int main() {
signal(SIGALRM,wakeUp);
alarm(1);
while(1);
return(0);
}
How to avoid while(1) in the above
I attached a code snippet for implementation kernel threads functions (you'll see that daemonize is used inside).
This an example of independent thread that will print something every 5 seconds and exit after repeating it 100 times:
static void my_thread(kthread_t *kthread)
{
int f;
init_kthread(kthread, "my_thread");
for (f=0; f<10; f++)
{
printk(KERN_INFO "Hello world");
sleep(5);
}
exit_kthread(kthread);
}
kthread_t my_thread_handle;
start_kthread(my_thread, &my_thread_handle);
while(1); is a no-no. It will soak up all available CPU.
Since you are already using SIGALRM, you cannot do while(1) sleep(1); because sleep() also uses SIGALRM.
But you *can* use nanosleep(), because it doesn't use any signals. The SIGALRM will interrupt it, so you can nanosleep as long as you like. You still need the while(1), but only to restart nanosleep once per SIGALRM received.
It is good practice to do as little as possible in a signal handler. Reinstating the signal handler is fine: to avoid that necessity, you can use the more modern sigaction call. Otherwise, best practice is to set a flag for the main program to action, and return. Calling printf() in particular is not a good idea, since the signal you are handling might have interrupted another printf() if you see what I mean.
See next post for some ideas
It's always a good idea to compile with option "-Wall". Also I always use "-Wstrict-prototypes -Wmissing-prototypes", which has found a few problems for me in the past.
12:31:05$ gcc -Wall -g3 -ggdb ee52.c -o ee52
ee52.c: In function 'wakeUp':
ee52.c:10: warning: passing argument 2 of 'signal' from incompatible pointer type
ee52.c:11: warning: implicit declaration of function 'alarm'
ee52.c:13: warning: control reaches end of non-void function
ee52.c: In function 'main':
ee52.c:16: warning: passing argument 2 of 'signal' from incompatible pointer type
Ok they're just warnings, but a warning can indicate a program which will nor tun correctly. So let's fix them:-
ee52.c:10: warning: passing argument 2 of 'signal' from incompatible pointer type: from the man page, we see that the signal handler given to signal() should be a function returning void (i.e. not returning anything) and taking an integer argument. Make that change and try again:
4c4
< int wakeUp() {
---
> void wakeUp(int signum) {
12:43:12$ gcc -Wall -g3 -ggdb ee52.c -o ee52
ee52.c: In function 'wakeUp':
ee52.c:11: warning: implicit declaration of function 'alarm'
We are missing the header that describes the alarm() system call. From "man -s 2 alarm" we see that it is unistd.h, so insert it:
2a3
> #include <unistd.h>
12:50:39$ gcc -Wall -g3 -ggdb ee52.c -o ee52
12:50:44$
The warning-free program is the 1st listing below.
Humor an old man and let's fix -Wstrict-prototypes -Wmissing-prototypes:-
12:56:14$ gcc -Wall -g3 -ggdb ee52.c -o ee52 -Wstrict-prototypes -Wmissing-prototypes
ee52.c:9: warning: no previous prototype for 'wakeUp'
ee52.c:17: warning: function declaration isn't a prototype
One could fix "no previous prototype" by inserting the line:
void wakeUp(int signum);
as a prototype before the function declaration. But there's a quicker way (in terms of programmer's time) - just make it static. It is a style of programming that not everyone agrees with (to put all static declarations before the mainline thus avoiding the need for prototypes) but a common style nevertheless.:
< void wakeUp(int signum) {
---
> static void wakeUp(int signum) {
13:08:05$ gcc -Wall -g3 -ggdb ee52.c -o ee52 -Wstrict-prototypes -Wmissing-prototypes
ee52.c:17: warning: function declaration isn't a prototype
The "function declaration isn't a prototype" message appears because you declared main() with empty parentheses. Gcc can't be sure if that isn't an old-style function declaration (you don't want to know about those:) so raises a warning. You explicitly have to tell gcc that main() takes no arguments
17c17
< int main() {
---
> int main(void) {
13:14:54$ gcc -Wall -g3 -ggdb ee52.c -o ee52 -Wstrict-prototypes -Wmissing-prototypes
13:15:02$
Hope you're still reading - now to fix the program:
7a8,12
> #include <time.h> /* For nanosleep */
>
> #define WAIT_TIME 5
>
> static int flag = 0; /* For the handler to set */
11d15
< printf("Wake up \n");
13c17,18
< alarm(1);
---
> alarm(WAIT_TIME);
> flag = 1;
17a23,27
>
> struct timespec req; /* Requested wait time */
>
> req.tv_sec = 1;
> req.tv_nsec = 500000000;
19,20c29,38
< alarm(1);
< while(1);
---
> alarm(WAIT_TIME);
> while(1)
> {
> nanosleep(&req, NULL);
> if (flag)
> {
> flag = 0;
> printf("Woken by alarm - do your processing here\n");
> }
> }
I changed back to 5 second alarm as you originally mentioned.
The nanosleep time is less than the alarm time just in case the alarm gets missed (most unlikely). You could have a nanosleep time of 100 seconds. Best not to make it an exact fraction of the alarm time - you could just possibly miss an alarm if it went off outside of nanosleep. Hence I set it at 1.5 secs.
If you can find the running program in "top", it certainly stays in the S state.
I really would caution against doing your processing in the signal handler even though in this simple example you might get away with it.
I think GMainloop waits for X events. As such, it is likely doing (select or poll) or a blocking i/o. You could find out what exactly it is doing by using the strace command e.g.
strace -p $(pgrep YourApp)
where "YourApp" is the name of your program. strace won't tell you this, but GMainloop is probably in a while(1) loop or the equivalent. So you are simply (and unnecessarily) getting another package to do your dirty work for you.
In my last post, I think I forgot to mention that nanosleep() will get interrupted when the alarm goes off, so timing will be as accurate as alarm() is.
There's an S against it in top. (You can only see it in top by using -p {pid of program} unless you have so few processes that they all fit on your screen).
From man top:
w: S -- Process Status
The status of the task which can be one of:
'D' = uninterruptible sleep
'R' = running
'S' = sleeping
'T' = traced or stopped
'Z' = zombie
Tasks shown as running should be more properly thought of as 'ready to run' -- their task_struct is simply represented on the Linux run-queue. Even without a true SMP machine, you may see numerous
tasks in this state depending on top's delay interval and nice value.
Business Accounts
Answer for Membership
by: natokaPosted on 2009-10-29 at 03:30:02ID: 25692095
I can only understand that you want to call a function every 5 seconds.
Please provide more information.