Question

I have a C program that polls some hardware sensors once a minute, and adds the readings to a database. To ensure that the readings are taken closer to minutely (instead of minutely + overhead time), the program creates a child to do the actual work, and then sleeps for 60 seconds before creating another child.

The trouble I'm having is that the SIGCHLD from the children are interrupting the sleep(60), causing unlimited children to be created, instead of one per minute.

This is how I've been trying to do it:

while(1)
{

    /* Create a child to do the work */
    if((pid = fork()) < 0)
    {
        perror("fork");
        exit(1);
    }
    else if(pid > 0)
    {
        /*parent continues*/
        select(0, 0, NULL, NULL, &time);
        claim_children();
        continue;
    }
    /*Now in the child*/
    process_pvs();
}

I've also heard that select() can be used to achieve what I'm after by doing the following:

struct timeval time;

time.tv_sec = 60;
time.tv_usec = 0;

select(0, 0, 0, 0, time);

But for some reason this only works for 1 iteration in the while loop. After that the program does not wait at all, and creates children constantly.

So how can I best have my program do this without being interrupted by sigchld?

Was it helpful?

Solution

You can ignore the child signal with

signal(SIGCHLD, SIG_IGN);

This will stop the interrupts, but you need to be careful that you wait for all children. Normally a loop to catch them all.

while(waitpid(-1, &status, WNOHANG) > 0);

This only works well if you aren't making other child processes elsewhere of course.

OTHER TIPS

You can simply code around it; detect the interrupted system call, note the time, and use logic to figure out if you need to go back into a sleep and if so, for how long.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top