睡眠(1)和睡眠(睡眠(1))之间的区别

时间:2017-12-13 05:08:20

标签: operating-system

在寻找sigchild代码时,我有以下代码。在下面的代码中,创建了50个子节点,父进程在sigchild处理程序中等待,直到所有50个子节点都被销毁。

如果我在main的末尾使用while(sleep(1)),我会得到预期的结果,但如果我用sleep(1)替换它,那么在所有子进程终止之前,父进程将被阻塞。

int l=0;
/* SIGCHLD handler. */
static void sigchld_hdl (int sig)
{
    /* Wait for all dead processes.
     * We use a non-blocking call to be sure this signal handler will not
     * block if a child was cleaned up in another part of the program. */
    while (waitpid(-1, NULL, WNOHANG) > 0) {
            printf("   %d",l++);
    }
    printf("\nExiting from child :: %d\n",l);

}

int main (int argc, char *argv[])
{

        struct sigaction act;
        int i;

        memset (&act, 0, sizeof(act));
        act.sa_handler = sigchld_hdl;

        if (sigaction(SIGCHLD, &act, 0)) {
            perror ("sigaction");
            return 1;
        }

        /* Make some children. */
        for (i = 0; i < 50; i++) {
            switch (fork()) {
                case -1:
                    perror ("fork");
                    return 1;
                case 0:
                    return 0;
            }
        }

        /* Wait until we get a sleep() call that is not interrupted by a signal. */
        while (sleep(1)) {
        }
      //      sleep(1);
            printf("\nterminating\n");
        return 0;

}

2 个答案:

答案 0 :(得分:0)

来自manual page

  

返回值

     

如果请求的时间已过,则为零,或秒数   如果呼叫被信号处理程序中断,则进入休眠状态。

所以我猜没有while位,睡眠就会中断,因此这个过程很快就会结束

答案 1 :(得分:0)

  

在寻找sigchild代码时,我有以下代码。在   创建了50个以下子代码,父进程等待   直到所有50个孩子都被摧毁之前,sigchild处理程序。

不,它没有。如果没有人退出,waitpid WNOHANG将会失败。并且无法保证在执行处理程序期间所有子项都退出(或将退出)。

即使只是睡觉(1),也无法保证任何孩子都能设法退出,但实际上大多数孩子都会退出。

睡觉是一种根本错误的方法。既然你知道你创造了多少个孩子,那么你应该等待所有孩子完成它们。例如,你可以在每次收获某些东西时减少现有孩子的计数器并等待它变为0。

根据真实程序的样子,你可能不想在第一时间使用处理程序:只需要循环结束,但没有WNOHANG。

我还要对此发表评论:

  

/ *等待所有死进程。        *我们使用非阻塞调用来确保此信号处理程序不会        *阻止孩子在该计划的另一部分被清理。 * /

您无法混合信号处理程序并自行等待。您冒险从等待它的其他代码中抢夺进程,然后会发生什么?

这是一个设计错误。 fork / exit行为必须统一或分散。