2011-11-17 28 views
4

被这些系统调用练习,但我stucked这个代码:理解叉(),睡眠()和流程通量

#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);替换它,那么flux的工作方式是如何设计的(无论如何,没有任何时间)。 在这一点上,我不再确定过程流量或sleep()使用情况(手册页没有那么有用,说实话太简洁)。

回答

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 
+0

非常感谢您的回答 – init6eb

+0

欢迎你,祝你学习的休息; - ) – BenC

1

的等待手册页说以下内容:

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

因为第一个孩子而等待回来。