通过SIGCHLD睡眠

时间:2012-10-08 13:01:15

标签: c sleep sigchld select-function

我有一个C程序,每分钟轮询一些硬件传感器,并将读数添加到数据库。为了确保读数接近于微小(而不是微小的+开销时间),程序会创建一个孩子来完成实际工作,然后在创建另一个孩子之前休眠60秒。

我遇到的麻烦是来自孩子的SIGCHLD正在打断睡眠(60),造成无限制的孩子被创造,而不是每分钟一次。

这就是我一直在尝试的方式:

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

我也听说过select()可以通过以下方式实现我所追求的目标:

struct timeval time;

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

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

但由于某种原因,这仅适用于while循环中的1次迭代。之后,程序根本不会等待,并不断创建孩子。

那么我怎样才能最好地让我的程序在没有被sigchld打断的情况下做到这一点?

2 个答案:

答案 0 :(得分:2)

你可以简单地编码;检测中断的系统调用,记下时间,并使用逻辑确定是否需要重新进入睡眠状态,如果需要,可以查看多长时间。

答案 1 :(得分:1)

您可以使用

忽略子信号
signal(SIGCHLD, SIG_IGN);

这将停止中断,但你需要小心等待所有孩子。通常是一个循环来捕捉它们。

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

这只适用于当然不在其他地方制作其他子进程的情况。