理解fork(),sleep()和进程通量

时间:2011-11-17 12:41:45

标签: c linux fork sleep

正在练习那些系统调用,但我坚持使用这段代码:

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

main()
{
    pid_t pid;
    switch(pid = fork())
    {
        case -1:
            printf("fork failed");
            break;
        case 0:  //first child
            printf("\ni'm the first child, my pid is %d", getpid());
            fflush(stdout);
            break;
        default:    //parent
            sleep(5); /** sleep is generating problems **/
            printf("\ni'm the parent process, my pid is %d", getpid());
            printf("\ngenerating a new child");
            fflush(stdout);
            switch(pid = fork())
            {
                case -1:
                    printf("fork failed");
                    break;
                case 0: //second child
                    printf("\nhere i am, the second child, my pid is %d", getpid());
                    break;
                default:  //parent
                    wait((int *)0);
                    printf("\nback to parent, my pid is %d", getpid());
            }
    }

    return 0;
}

我得到的输出是:

i'm the first child, my pid is 6203
i'm the parent process, my pid is 6202
generating a new child
back to parent, my pid is 6202
Process returned 0 (0x0)   execution time: 5.004 s
Press ENTER to continue

here i am, the second child, my pid is 6204

我正在尝试的是通过sleep()管理时间的这些消息的简单打印。 我无法理解为什么程序在打印第二个子消息之前返回。 默认情况(第二个分支之后的那个)在其子(第二个)作用于输出之前被打印,就像他忽略了它的wait()一样。因此,它的孩子在过程返回后被打印出来。

我无法弄清问题是什么。我已经标记了sleep()函数,因为如果我用wait((int *)0);替换它,那些进程的工作方式是如何设计的(无论如何,没有任何时间)。 在这一点上,我不再确定过程流量,或睡眠()用法(手册页没有那么有用,说实话太简洁了。)

2 个答案:

答案 0 :(得分:4)

实际上,你的等待电话有效。它会检测第一个子进程的结束并在之后继续。如果你连续两次调用wait(),你将得到正确的行为。

更新了测试代码:

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

main()
{
    pid_t pid;
    int status;
    switch(pid = fork())
    {
        case -1:
            printf("fork failed");
            break;
        case 0:  //first child
            printf("\ni'm the first child, my pid is %d", getpid());
            fflush(stdout);
            break;
        default:    //parent
            sleep(5); /** sleep is generating problems **/
            printf("\ni'm the parent process, my pid is %d", getpid());
            printf("\ngenerating a new child");
            fflush(stdout);
            switch(pid = fork())
            {
                case -1:
                    printf("fork failed");
                    break;
                case 0: //second child
                    printf("\nhere i am, the second child, my pid is %d", getpid());
                    break;
                default:  //parent
                    pid = wait(&status);
                    printf("\nParent detects process %d was done", pid);
                    pid = wait(&status);
                    printf("\nParent detects process %d was done", pid);
                    printf("\nback to parent, my pid is %d", getpid());
            }
    }

    return 0;
}

输出

i'm the first child, my pid is 30897
i'm the parent process, my pid is 30896
generating a new child

here i am, the second child, my pid is 30940
Parent detects process 30897 was done
Parent detects process 30940 was done
back to parent, my pid is 30896

答案 1 :(得分:1)

等待的手册页说明如下:

  

wait()函数应暂停执行调用线程,直到调用进程的一个已终止子进程的状态信息可用,或者直到传递其动作是执行信号捕获功能的信号或终止这个过程。如果等待终止相同进程的wait()或waitpid()中挂起了多个线程,则只有一个线程应在目标进程终止时返回进程状态。

由于第一个孩子,等待回来了。