简体   繁体   English

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

[英]read system call returns -1 when reading from pipe in child process

To learn how Pipe IPC mechanism works, I wrote a simple program that creates two child processes which share data using a pipe. 为了了解Pipe IPC机制的工作原理,我编写了一个简单的程序,该程序创建了两个子进程,这些子进程使用管道共享数据。 The first child process has to read data from a file and pass it to the pipe. 第一个子进程必须从文件读取数据并将其传递到管道。

Afterwards, the second child process has to read it, convert it to uppercase and write it to another file. 之后,第二个子进程必须读取它,将其转换为大写并将其写入另一个文件。 The read system call in the second child process returns -1 when reading from the pipe. 从管道读取时,第二个子进程中的read系统调用返回-1。 Also when I execute the program, in some cases printf in the first child does not print anything and in other cases printf in the second child does not print, too. 同样,当我执行程序时,在某些情况下,第一个孩子中的printf不会打印任何内容,而在其他情况下,第二个孩子中的printf也不会打印。 Could you please point the mistakes in the program which are causing the problems? 您能否指出导致问题的程序错误?

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;
}

There are few things to take into account here. 这里有几件事要考虑。 First thing i would like to point is that you do not need to use two fork() calls. 我想指出的第一件事是,您不需要使用两个fork()调用。 In that case you have three processes working in parallel (parent process and two child process, one per each fork() call). 在这种情况下,您有三个并行工作的进程(父进程和两个子进程,每个fork()调用一个)。

One important point to take into account when you work with processes working in parallel is synchronism. 在并行处理流程时要考虑的重要一点是同步。 In your code you are creating two processes. 在您的代码中,您正在创建两个过程。 Parent process does not wait for any of its child, so it finishes its execution, and if child processes have not finished, they will become child of init process. 父进程不等待其子进程中的任何一个,因此它完成了执行,如果子进程尚未完成,则它们将成为init进程的子进程。 But appart from that, you have the typical producer consumer problem. 但是,从此看来,您遇到了典型的生产者消费者问题。 One of your child produce something and the other consume it, but how they work in parallel, consumer need to know that the product is ready to be consumed. 您的一个孩子生产某种东西,另一个孩子消费它,但是他们如何并行工作,消费者需要知道该产品已经准备好可以消费了。 So, in this case, i think the easiest way to do this job is to use just one fork(), so child become the producer and the parent process (the consumer) wait until its child finish the job. 因此,在这种情况下,我认为完成此工作的最简单方法是仅使用一个fork(),因此子进程成为生产者,父进程(消费者)等待其子进程完成工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM