【问题标题】:Unix pipe experiment hangsUnix管道实验挂起
【发布时间】:2016-02-02 20:07:03
【问题描述】:

问题是这个程序不会输出预期的START和END,也不会退出,除非我从shell中杀死它。

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <unistd.h>

void check(bool b, const char *cp) {
    if (!b) {
        perror(cp);
        exit(EXIT_FAILURE);
    }
}

int main(void) {
    int fd[2];
    check(pipe(fd) != -1, "pipe");
    pid_t pid = fork();
    check(pid != -1, "fork");
    if (pid == 0) {
        check(dup2(1, fd[1]) != -1, "dup2");
        check(execlp("ls", "ls", NULL) != -1, "execlp");
    } else {
        char cs[10000];
        read(fd[0], cs, sizeof cs);
        printf("START\n%s\nEND\n", cs);
    }
    return EXIT_SUCCESS;
}

【问题讨论】:

    标签: c linux unix pipe


    【解决方案1】:

    您将 dup2( existing_fd, new_fd ) 参数的顺序颠倒了。

    您还有另一个错误,它破坏了许多 “让我们试试 pipe(2)” 实验。您没有关闭在叉上重复的管道末端。这通常会导致另一种挂起,因为读取器永远不会看到 EOF,因为读取器进程有管道写入器端的额外副本,因此仅关闭写入器进程的端部不足以为读取器提供 EOF。

    所以,养成习惯:

    if (pid == 0) {
        check(dup2(fd[1], 1) != -1, "dup2");
        close(fd[1]); // Here!
        close(fd[0]); // ...and here!
        check(execlp("ls", "ls", NULL) != -1, "execlp");
    } else {
        char cs[10000];
        close(fd[1]); // and here!
        ...
    }
    

    【讨论】:

      猜你喜欢
      • 2012-09-14
      • 1970-01-01
      • 2011-10-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-25
      • 2015-12-07
      相关资源
      最近更新 更多