【问题标题】:I used wait(&status) and the value of status is 256, why?我用了wait(&status),status的值为256,为什么?
【发布时间】:2014-07-30 15:00:57
【问题描述】:

我的代码中有这一行:

t = wait(&status); 

子进程工作时status的值为0,嗯。

但是为什么它不起作用时返回 256 呢?为什么在出现错误时更改子进程中退出的参数值不会改变任何内容(例如,exit(2) 而不是 exit(1))?

谢谢

编辑:我在 linux 上,我用 GCC 编译。

我这样定义状态

int status;
t = wait(&status); 

【问题讨论】:

  • 问:什么平台?视窗? Linux?问:什么编译器?微博?海合会? Q:你是如何定义“状态”的? int status?
  • 请展示一个最小的例子。
  • 你错了。 exit(2) 将返回 512,而不是 256(假设 linux 或类似系统)。退出值编码在第二低字节中,而最低字节编码有关进程终止原因的信息(例如信号编号)。
  • 这就是我指定它的原因...它总是返回 256。

标签: c wait


【解决方案1】:

建议:尝试以下“进程完成状态”宏之一:

http://www.gnu.org/software/libc/manual/html_node/Process-Completion-Status.html

示例:

  int status = 0;
  ..
  int retval = wait (&status);
  if (WIFEXITED(status)) 
    printf("OK: Child exited with exit status %d.\n", WEXITSTATUS(status));
  else
    printf("ERROR: Child has not terminated correctly.\n");

【讨论】:

    【解决方案2】:

    给定这样的代码...

    int main(int argc, char **argv) {
        pid_t pid;
        int res;
    
        pid = fork();
        if (pid == 0) {
            printf("child\n");
            exit(1);
        }
    
        pid = wait(&res);
        printf("raw res=%d\n", res);
    
        return 0;
    }
    

    ...res 的值将是 256。这是因为来自wait 的返回值既编码了进程的退出状态,也编码了进程退出的原因。通常,您不应尝试直接解释来自wait 的非零返回值;您应该使用 WIF... 宏。比如看一个进程是否正常退出:

     WIFEXITED(status)
             True if the process terminated normally by a call to _exit(2) or
             exit(3).
    

    然后获取退出状态:

     WEXITSTATUS(status)
             If WIFEXITED(status) is true, evaluates to the low-order 8 bits
             of the argument passed to _exit(2) or exit(3) by the child.
    

    例如:

    int main(int argc, char **argv) {
        pid_t pid;
        int res;
    
        pid = fork();
        if (pid == 0) {
            printf("child\n");
            exit(1);
        }
    
        pid = wait(&res);
        printf("raw res=%d\n", res);
    
        if (WIFEXITED(res))
            printf("exit status = %d\n", WEXITSTATUS(res));
        return 0;
    }
    

    您可以在wait(2) 手册页中阅读更多详细信息。

    【讨论】:

    • 您的意思是在您的示例中使用wait 吗?使用system 有点模糊了这与wait 的关系。
    • 呃,我完全间隔了。让我解决这个问题。请注意,此示例实际上可以正常工作,因为 system() 调用发出的 fork() 的返回状态保持不变,但您说得对,这在技术上是有问题的。
    【解决方案3】:

    状态码包含有关子进程如何退出的各种信息。提供了宏来从状态码中获取信息。

    来自 linux 上的wait(2)

    If status is not NULL, wait() and waitpid() store status information in the int to which it points.  This integer can be inspected with the following macros (which take the integer itself as an argu-
       ment, 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 be employed only 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 be employed only if WIFSIGNALED returned true.
    
       WCOREDUMP(status)
              returns true if the child produced a core dump.  This macro should be employed only 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 possible only 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 be employed only if WIFSTOPPED returned true.
    
       WIFCONTINUED(status)
              (since Linux 2.6.10) returns true if the child process was resumed by delivery of SIGCONT.
    

    【讨论】:

      猜你喜欢
      • 2021-04-06
      • 2016-07-30
      • 1970-01-01
      • 1970-01-01
      • 2017-05-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-24
      相关资源
      最近更新 更多