【问题标题】:C - Child Process Not ExecutingC - 子进程未执行
【发布时间】:2016-11-11 05:44:22
【问题描述】:

[已解决] 所以对于这个练习练习,我被分配到练习过程控制。我只是想知道为什么我的子进程似乎永远不会执行(当 child_pid == 0 时)。对此问题的任何帮助将不胜感激! 另外,safe_fork() 是我们的讲师为了避免学生打开太多进程而编写的一个函数。

#include "safe-fork.h"
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>

int main(void) {

  pid_t child_pid;
  int pipefd[2];
  int pipe_result;
  int count;

  pipe_result = pipe(pipefd);

  if (pipe_result == -1) {
    perror("pipe failure");
    exit(1);
  }

  child_pid = safe_fork();

  /*Parent Process*/
  if (child_pid > 0) {
    dup2(pipefd[0], STDIN_FILENO);
    scanf("%d", &count);

    if (count > 200) {
      printf("Long enough!\n");
      exit(0);
    }
    else {
      printf("Too short!\n");
      exit(1);
    }

  }
  /* Child Process */
  else {
    dup2(pipefd[1], STDOUT_FILENO);
    execl("/usr/bin/wc", "-w");
  }
  return 0;
}

【问题讨论】:

  • 在调用任何scanf() 系列函数时,始终检查返回值(而不是参数值)以确保操作成功。当调用任何exec() 系列函数时,它们只会在发生错误时返回,因此在调用之后使用:perror( "exec?? failed"); exit(1);
  • 父进程应该调用waitpid( child_pid, NULL ); before returning. In the current scenario, the child will never return because no file/input is passed to the wc` 函数,这样它就会永远坐着,看着标准输入,进行输入。建议添加另一个参数,即要计算这些单词的文件名。注意:execl() 的参数列表应以 NULL 参数结尾。注意:退出父进程会使子进程(如果它尚未退出,在这种情况下它还没有退出)进入zombie进程,需要重新启动才能消除。
  • 调用fork()时,返回值是三个,而不是两个,(即-1错误)代码需要正确处理-1返回值。
  • execl() 函数的调用具有以下语法:int execl(const char *path, const char *arg, ... /* (char *) NULL */); 所以这一行:execl("/usr/bin/wc", "-w"); 应该更像:execl("/usr/bin/wc", "-w", file.txt, (char *) NULL );
  • 建议每个 4 级空格缩进,因为即使是可变宽度字体也可以看到

标签: c multithreading unix multitasking


【解决方案1】:

这是一个建议,明确检查 child_pid == 0 导致您的 safe_fork() 函数也可能失败,同时检查这些错误,即 child_pid

还请查看tutorial 以在 C 中创建管道并使用它们在父进程和子进程之间进行通信。我觉得您处理这些文件描述符的方式存在一些问题。您看不到任何输出的一个可能原因是 wc 可能仍在等待某些输入。

在检查其输出之前,您可能需要等待子进程完成/做一些有用的事情或实际运行。在您担心这个之前,请先检查其他问题。

希望这会有所帮助:)

【讨论】:

    【解决方案2】:

    是的,但不是。首先你要仔细理解fork()的含义。
    fork():创建一个子进程,它返回到两个进程,每个进程的返回值不同。 在父进程中,它总是返回操作系统为新创建的子进程 ID 分配的编号。同时它也会在新创建的子进程中返回,因为子进程将在 fork() 语句之后开始执行从父进程复制的代码。在子叉子中总是返回零。因此,通常在 fork() 系统调用之后,人们通过 fork 检查返回值以区分子进程和父进程。

    特别是在这种情况下,在 fork() 之后,将有两个进程具有相同的代码和相同的程序状态(除了在 child_pid 变量中分配的值不同)。在父级中,它是一个非零值(对应于子级的 pid),在子级中,它的值为零,因为叉子在子级中返回零。 现在两个进程都将执行

    if (child_pid > 0)
    

    仅对父进程为真,因此父进程将流入'if block',对子进程为假,因此它将直接跳转到else部分并执行else块。

    如果 child_process id 为零怎么办?
    操作系统将始终为孩子分配一个非零值,以便 fork() 可以工作。如果您以某种方式将子进程 ID 设为零,则父进程将无法进入“if 块”并执行与子进程相同的 else 块。

    【讨论】:

      猜你喜欢
      • 2012-10-15
      • 2014-08-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-21
      • 1970-01-01
      相关资源
      最近更新 更多