Unix管道实验挂起

时间:2016-02-02 20:07:03

标签: c linux unix pipe

问题是该程序不会输出预期的STARTEND,除非我从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;
}

1 个答案:

答案 0 :(得分:4)

您已将 dup2( existing_fd,new_fd 参数的顺序颠倒过来。

你还有另一个错误,打破了很多&#34;让我们尝试使用pipe(2)&#34; 实验。您没有关闭在fork上复制的管道末端。这通常导致不同类型的挂起,因为读者没有看到EOF,因为读者进程有一个管道编写者端的额外副本,因此只关闭作者进程的结束isn&n #39;足以给读者一个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!
    ...
}