【问题标题】:Why is my second child process being hit before my first?为什么我的第二个子进程在我的第一个子进程之前被击中?
【发布时间】:2019-03-22 16:00:20
【问题描述】:

目前,我正在尝试编写一个支持管道的小外壳。在我的函数execute(char** args, char** args2) 中,它需要两个字符数组,其中每个命令由分隔符" " 分割。第一个参数包含管道之前的命令(例如{ls, -l},第二个参数包含管道之后的命令(例如{wc})。

然而,在我的 execute 函数中,第二个子进程 pid2 首先运行,而第一个子进程 pid1 永远不会被命中。

我不确定我是否遗漏了在 C 中创建自己的管道命令所必需的任何内容,并且非常感谢我能得到的任何帮助/建议。

执行函数:

int execute(char** args, char** args2) {
    int des_p[2];
    pid_t pid1, pid2; 
    if(pipe(des_p) == -1) {
        perror("Pipe failed");
        exit(1);
    }
    pid1 = fork();
    if(pid1 == 0) {
        printf("AT FIRST CHILD");
        dup2(des_p[1], STDOUT_FILENO);
        close(des_p[0]);
        execvp(args[0], args);
        perror("execvp of of FIRST PROCESS failed");
        exit(1);
    }
    pid2 = fork();
    if(pid2 == 0) {
        printf("AT SECOND CHILD \n");
        dup2(des_p[0], STDIN_FILENO);
        close(des_p[1]);
        execvp(args2[0], args2);
        perror("execvp of SECOND PROCESS failed");
        exit(1);
    }
    close(des_p[0]);
    close(des_p[1]);
    wait(pid1);
    wait(pid2);

    return 0;
}

【问题讨论】:

  • 当您有多个进程时,它们可以按任意顺序运行。
  • 尝试在所有printf() 调用的末尾添加\n。 stdout 是行缓冲的,因此在换行之前不会打印任何内容。
  • 使用带有 dup2 的管道时的一般经验法则:close(fd[0]); dup2(fd[1], x); close(fd[1]);。也就是说,首先关闭你不打算使用的管道的末端。然后直到你要使用的最后。然后关闭dup'd结束。你没有关闭足够的 fds。

标签: c shell command pipe


【解决方案1】:

第一个子进程正在运行,但由于 stdio 缓冲,您没有看到消息。默认情况下,stdout 是行缓冲的,因此在打印换行符之前不会刷新缓冲区。您正在打印一条没有换行符的消息,然后在刷新缓冲区之前调用execvp(),因此缓冲区永远不会被刷新并且消息永远不会被看到。

改成:

    printf("AT FIRST CHILD\n");

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多