首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >等待状态(pid、状态、选项)并不总是设置状态

等待状态(pid、状态、选项)并不总是设置状态
EN

Stack Overflow用户
提问于 2013-05-13 16:03:18
回答 2查看 1.1K关注 0票数 0

我正在为一项任务复制贝壳管道。我让管道全部正常工作(从那以后还没有更改管道代码,所以这是已知的),但是在管道的某个步骤出现执行失败时,仍然需要终止管道。在实现该代码时,管道开始显示出意想不到的行为。

长度为2的管道工作正常。长度大于两条的管道以下列方式失效:

  1. 执行管道中的第一个命令。
  2. 紧接着--通常是在第一个命令完成执行之前--管道中的最终命令终止。
  3. 然后,第二个命令将挂起,显然没有收到来自第一个命令的输入。

下面是使用waitpid的部分代码(sans调试代码):

代码语言:javascript
复制
for (int i = 0 ; i < num_cmds ; i++) {
  if (waitpid(cmd_pids[i], &cmd_status[i], NULL) != cmd_pids[i]) {
     printf("Error waiting for command %s\n", cmds[i]);
     perror("Error");
  }
  if ((cmd_status[i] > 0) && (cmd_status[i-1] == 0)) {
     killPipeline(SIGINT); //Kill pipeline; something failed
  }
  fflush(logfp);

}

下面是我认为应该归咎于waitpid部分的关键部分:由于赋值要求的一些奇怪的控制流,我发现将cmd_status的值初始化为-2很方便。日志函数将子进程的返回状态打印到日志中,该文件表示第二个函数的退出状态为-2,这当然意味着它没有在程序上设置存在状态。看来管道根本没有在等待这些程序的执行。

输入"ls \ grep管道\ wc“

产出:

代码语言:javascript
复制
You entered : list of pipe commands  ls | grep pipe | wc
Creating process ls
Creating process grep pipe
Creating process wc
Waiting for command ls
      0       0       0 //wc received no input, but somehow an EOF
Command ls finished
Waiting for command grep
^C  //Terminate grep because it's waiting for input from a terminated process
Error waiting for command grep
Error: Interrupted system call
Command grep finished
Waiting for command wc
Command wc finished
EN

回答 2

Stack Overflow用户

发布于 2013-05-13 16:07:03

要提取通过进程传递给exit()的状态,waitpid()返回的值使用宏WEXITSTATUS()

此外,对waitpid()失败的测试也是错误的。waitpid() return -1 on failure and in this case seterrno, which then would make sense to be interpreted by a call toperror()`。

perror()读取errno的值。因此,只有在已知已设置perror()的情况下,调用errno才有意义。我在修改代码时删除了对perror("Error")的调用,但情况并非如此,如下所示。

代码语言:javascript
复制
for (int i = 0 ; i < num_cmds ; i++) 
{
  int status = -1;
  int result = waitpid(cmd_pids[i], &status, NULL);
  if (-1 == result)
  {
    perror("waitpid()"); /* added call to perror() here as errno is know to have been set */
  }
  else
  { 
    if (result != cmd_pids[i]) 
    {
      fprintf(stderr, "Error waiting for command '%s'\n", cmds[i]);
      /* removed call to perror() here as errno had not been set here. As this however should
         log an error, I modded the code to printf to stderr, but stdout. */
    }
    else
    {
      cmd_status[i] = WEXITSTATUS(status);

      if ((cmd_status[i] > 0) && ((0 == i) || (cmd_status[i-1] == 0))) /* This mod keeps   
        the app from dereferencing cmd_status in case i == 0, as this would lead to 
        cmd_status[-1], which is undefined beaviour. */
      {
        killPipeline(SIGINT); //Kill pipeline; something failed
      }
    }
  }
  ...
票数 1
EN

Stack Overflow用户

发布于 2013-05-13 17:43:24

向那些试图找出与waitpid有关的任何问题的人道歉,因为它们只是表面上的错误。实际的错误确实存在于我的管道代码中,这显然是我沿途被破坏的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16526421

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档