【问题标题】:What does the second parameter of waitpid() mean?waitpid() 的第二个参数是什么意思?
【发布时间】:2012-08-06 08:14:43
【问题描述】:

从一个现有的问题here,有人给出了这个示例代码:

int status;
child_pid = fork();
if (child_pid == 0) {
     // in child; do stuff including perhaps exec
} else if (child_pid == -1) {
     // failed to fork 
} else {
     if (waitpid(child_pid, &status, 0) == child_pid) {
          // child exited or interrupted; now you can do something with status
     } else {
          // error etc
     }
 }

谁能给我解释一下waitpid()的第二个参数是干什么用的?

【问题讨论】:

    标签: c pid


    【解决方案1】:

    来自手册页:

       If  status is not NULL, wait() and waitpid() store status infor-
       mation in the int to which  it  points.   This  integer  can  be
       inspected  with  the  following  macros  (which take the integer
       itself as an argument, not a pointer to it, as is done in wait()
       and waitpid()!):
    
       WIFEXITED(status)
              returns  true  if the child terminated normally, that is,
              by calling exit(3) or  _exit(2),  or  by  returning  from
              main().
    
       WEXITSTATUS(status)
              returns  the  exit status of the child.  This consists of
              the least significant 8 bits of the status argument  that
              the  child  specified in a call to exit(3) or _exit(2) or
              as the argument for a return statement in  main().   This
              macro should only be employed if WIFEXITED returned true.
    
       WIFSIGNALED(status)
              returns true if the child process  was  terminated  by  a
              signal.
    
       WTERMSIG(status)
              returns  the  number  of the signal that caused the child
              process to terminate.  This macro should only be employed
              if WIFSIGNALED returned true.
    
       WCOREDUMP(status)
              returns  true  if  the  child produced a core dump.  This
              macro should only be  employed  if  WIFSIGNALED  returned
              true.  This macro is not specified in POSIX.1-2001 and is
              not available on some Unix  implementations  (e.g.,  AIX,
              SunOS).   Only  use this enclosed in #ifdef WCOREDUMP ...
              #endif.
    
       WIFSTOPPED(status)
              returns true if the child process was stopped by delivery
              of  a  signal; this is only possible if the call was done
              using WUNTRACED or when the child is  being  traced  (see
              ptrace(2)).
    
       WSTOPSIG(status)
              returns  the  number of the signal which caused the child
              to stop.  This macro should  only  be  employed  if  WIF-
              STOPPED returned true.
    
       WIFCONTINUED(status)
              (since  Linux  2.6.10)  returns true if the child process
              was resumed by delivery of SIGCONT.
    

    因此它存储“孩子如何终止”的状态。

    您可以使用宏来调查孩子究竟是如何终止的,并且您可以根据孩子的终止状态定义一些操作。

    【讨论】:

    • +1 很好地解释了“孩子是如何终止的”,如果状态是 int(如 1,2,3,4,5),每个都代表终止状态,为什么将其声明为 pid_t类型,而不是 int 类型
    • 对于可移植性问题,它隐藏在 typedef 下。这样平台的原生整数类型就可以不同,而不会破坏使用过程控制系统调用(如fork()waitpid())的代码。
    • 哇,我想我需要更多地了解线程编程才能理解这一点。听起来很深沉,很有趣
    【解决方案2】:

    是options的bit-field,唯一可用的是WNOWAIT,意思是让child处于等待状态;稍后的等待调用可用于再次检索子状态信息。

    见:http://linux.die.net/man/2/waitpid

    【讨论】:

    • 感谢您的快速回复,我要问的是&status 部分,status 参数用于什么
    • 对不起,我错过了,这是程序的当前状态,您可以使用宏来测试每个条件,例如WIFEXITEDWIFSIGNALED。有关这些信息,请参见相同的 URL。
    • 知道了,waitPid 实际上将状态存储在那个变量中,
    • status变量其实是一个int,值为0,单个int怎么传给不同的函数(WIFEXITED WIFSIGNALED)得到不同的结果,我很困惑
    • 我想明白了,status 可以是一个数字范围,不是只有 0 和 1 吗?
    【解决方案3】:
          pid = fork();
          if(pid < 0)
          {
            printf("fork failed\n");
            return -1;
          }
          else if(pid == 0)
          {
            sleep(5);
            printf("Child process\n");
            return 2;
          }
          else
          {
            printf("Parent process\n");
            kill(pid, SIGKILL);
            waitpid(pid, &ret, 0);
            if(WIFEXITED(ret))
              printf("Child process returned normally\n");
            if(WIFSIGNALED(ret))
              printf("Child process terminated by signal\n");
            return 1;
          }
    

    如您所见,返回值可用于检查特定进程如何终止并在此基础上采取行动。

    如果你注释掉代码中的kill line,子进程会正常终止。

    【讨论】:

      猜你喜欢
      • 2011-10-22
      • 2016-10-05
      • 1970-01-01
      • 1970-01-01
      • 2011-09-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-06
      • 1970-01-01
      相关资源
      最近更新 更多