关闭管道得到坏文件描述符

时间:2016-03-29 20:06:26

标签: c pipe

以下是代码:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>

int main(int argc, char **argv) {

int num = 2;
pid_t pid;
int i;

int p1[num][2], p2[num][2];
for (i = 0; i < num; i++) {
    if (pipe(p1[i]) == -1) {
        perror("pipe");
        exit(1);
    }
    if (pipe(p2[i]) == -1) {
        perror("pipe");
        exit(1);
    }
}

for (i = 0; i < num; i++) {
    if ((pid = fork()) == 0) {
        if (close(p1[i][1]) != 0) {
            perror("close");
            exit(1);
        }
        if (close(p2[i][0]) != 0) {
            perror("close");
            exit(1);
        }
        printf("%d\n", getpid());
        exit(0);
    } else if (pid > 0) {
        if (close(p1[i][0]) != 0) {
            perror("close");
            exit(1);
        }
        if (close(p2[i][1]) != 0) {
            perror("close");
            exit(1);
        }
        continue;
    } else {
        perror("fork");
        exit(1);
    }   
}

for (i = 0; i < num; i++) {
    if (close(p1[i][0]) != 0) {
        perror("close1"); // <----error
    }
    if (close(p1[i][1]) != 0) {
        perror("close");
    }
    if (close(p2[i][0]) != 0) {
        perror("close");
    }
    if (close(p2[i][1]) != 0) {
        perror("close2"); // <----error
    }
}
for (i = 0; i < num; i++) {
    if (wait(NULL) == -1) {
        perror("wait");
        exit(1);
    }
}
return 0;
}

当我运行它时,它会给我输出

close1: Bad file descriptor
close2: Bad file descriptor
close1: Bad file descriptor
close2: Bad file descriptor
8798
8799

我要做的是创建两个2D数组管道和fork num次。 创建和运行都运行良好,但有些管道无法关闭。 似乎p1 [i] [0]和p2 [i] [1]永远不会更接近。

1 个答案:

答案 0 :(得分:0)

您获得EBADFD的原因是您尝试两次关闭相同的文件描述符。

我在第一段代码中添加了一个print语句来显示/跟踪正在关闭的文件描述符。如果您编译并运行它,您将看到在您尝试第二次关闭描述符后出现错误消息。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>

int main(int argc, char **argv) {

int num = 1;
pid_t pid;
int i;

int p1[num][2], p2[num][2];
for (i = 0; i < num; i++) {
    if (pipe(p1[i]) == -1) {
        perror("pipe");
        exit(1);
    }
    if (pipe(p2[i]) == -1) {
        perror("pipe");
        exit(1);
    }
}

for (i = 0; i < num; i++) {
    if ((pid = fork()) == 0) {
        printf("Child closing: Pipe1 %d End %d\n", i, 1);
        if (close(p1[i][1]) != 0) {
            perror("close");
            exit(1);
        }
        printf("Child closing: Pipe2 %d End %d\n", i, 1);
        if (close(p2[i][0]) != 0) {
            perror("close");
            exit(1);
        }
        printf("%d\n", getpid());
        exit(0);
    } else if (pid > 0) {
        printf("Parent closing: Pipe1 %d End %d\n", i, 0);
        if (close(p1[i][0]) != 0) {
            perror("close");
            exit(1);
        }
        printf("Parent closing: Pipe1 %d End %d\n", i, 1);
        if (close(p2[i][1]) != 0) {
            perror("close");
            exit(1);
        }
        continue;
    } else {
        perror("fork");
        exit(1);
    }   
}

for (i = 0; i < num; i++) {
    printf("Closing: Pipe1: %d End: %d\n", i, 0);
    if (close(p1[i][0]) != 0) {
        perror("close1"); // <----error
    }
    printf("Closing: Pipe1: %d End: %d\n", i, 1);
    if (close(p1[i][1]) != 0) {
        perror("close");
    }
    printf("Closing: Pipe2: %d End: %d\n", i, 0);
    if (close(p2[i][0]) != 0) {
        perror("close");
    }
    printf("Closing: Pipe2: %d End: %d\n", i, 1);
    if (close(p2[i][1]) != 0) {
        perror("close2"); // <----error
    }
}
for (i = 0; i < num; i++) {
    if (wait(NULL) == -1) {
        perror("wait");
        exit(1);
    }
}
return 0;
}

检查pid并关闭第一个循环内未关闭的末端。此代码假定您正在读取和写入特定管道,具体取决于孩子/父母的需要。您可能需要调整以适应您的用例:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>

int main(int argc, char **argv) {

int num = 1;
pid_t pid;
int i;

int p1[num][2], p2[num][2];
for (i = 0; i < num; i++) {
    if (pipe(p1[i]) == -1) {
        perror("pipe");
        exit(1);
    }
    if (pipe(p2[i]) == -1) {
        perror("pipe");
        exit(1);
    }
}

for (i = 0; i < num; i++) {
    if ((pid = fork()) == 0) {
        if (close(p1[i][1]) != 0) {
            perror("close");
            exit(1);
        }
        if (close(p2[i][0]) != 0) {
            perror("close");
            exit(1);
        }
        printf("%d\n", getpid());
        exit(0);
    } else if (pid > 0) {
        if (close(p1[i][0]) != 0) {
            perror("close");
            exit(1);
        }
        if (close(p2[i][1]) != 0) {
            perror("close");
            exit(1);
        }
        continue;
    } else {
        perror("fork");
        exit(1);
    }   
}

for (i = 0; i < num; i++) {
    if (pid == 0) {
        if (close(p1[i][0]) != 0) {
            perror("close1");
        }
        if (close(p2[i][1]) != 0) {
            perror("close");
        }
    } else {
        if (close(p1[i][1]) != 0) {
            perror("close");
        }
        if (close(p2[i][0]) != 0) {
            perror("close2");
        }
    }
}
for (i = 0; i < num; i++) {
    if (wait(NULL) == -1) {
        perror("wait");
        exit(1);
    }
}
return 0;
}