在子进程中从管道读取时,read系统调用返回-1

时间:2019-04-10 10:03:09

标签: c

要了解Pipe IPC机制的工作原理,我编写了一个简单的程序,该程序创建了两个子进程,这些子进程使用管道共享数据。第一个子进程必须从文件读取数据并将其传递到管道。

此后,第二个子进程必须读取它,将其转换为大写并将其写入另一个文件。从管道读取时,第二个子进程中的read系统调用返回-1。同样,当我执行程序时,在某些情况下,第一个孩子中的printf不会打印任何内容,在其他情况下,第二个孩子中的printf也不会打印。您能否指出导致问题的程序错误?

int main(int args[], char * argv[]) {

    int fd[2];

    long length;
    char buff1[250];
    char buff2[250];

    FILE * fptr1;
    FILE * fptr2;

    pid_t A, B;
    pipe(fd);

    A = fork();

    if (A == -1) {
        printf("error in fork of A\n");
        exit(1);
    }
    if (A == 0) {
        fptr1 = fopen(argv[1], "r"); // program receives file names as argument

        if (fptr1 == NULL) {
            printf("Erro in file open1\n");
            exit(1);
        }

        fseek(fptr1, 0 L, SEEK_END);
        length = ftell(fptr1);
        fseek(fptr1, 0 L, SEEK_SET);

        close(fd[0]);

        fread(buff1, length, 1, fptr1);
        buff1[length] = '\0';
        printf("buff1 = %s", buff1);
        write(fd[1], buff1, length);

        fclose(fptr1);
        exit(0);
    } else {
        B = fork();
        if (B == -1) {
            printf("Error in forking child B");
            exit(1);
        }
        if (B == 0) {
            fptr2 = fopen(argv[2], "w");

            if (fptr2 == NULL) {
                printf("Error in file open2\n");
                exit(1);
            }

            close(fd[1]);
            int n = read(fd[0], buff2, length);
            printf("n = %d\n", n);
            upper_string(buff2); // converts characters to uppecase
            fwrite(buff2, 1, length, fptr2);
            fclose(fptr2);
        }
    }
    return 0;
}

1 个答案:

答案 0 :(得分:0)

这里没有什么要考虑的。我想指出的第一件事是,您不需要使用两个fork()调用。在这种情况下,您有三个并行工作的进程(父进程和两个子进程,每个fork()调用一个)。

与并行工作的流程一起使用时,要考虑的重要一点是同步。在您的代码中,您正在创建两个过程。父进程不等待其子进程中的任何一个,因此它完成了执行,如果子进程尚未完成,则它们将成为init进程的子进程。但是,从此看来,您遇到了典型的生产者消费者问题。您的一个孩子生产某种东西,另一个孩子消费它,但是他们如何并行工作,消费者需要知道该产品已经准备好可以消费了。因此,在这种情况下,我认为完成此工作的最简单方法是仅使用一个fork(),因此子进程成为生产者,父进程(消费者)等待其子进程完成工作。