不了解管道的工作原理。 (进程间共享内存 UNIX)

Not understanding how the pipe works. (Shared memory between processes UNIX)

我不了解管道在 UNIX 中的工作原理,我编写了这段代码,但偶然发现了一个奇怪的事实。练习的痕迹可以在代码的顶部找到。我会解释我无法得到的东西。在父进程中,当我想打印管道中的值时,“i”变量开始的值可以是任何数字。我放了“4”,但它适用于每个数字 2、3、4 等等。 怎么每次都行?

/*****************************************************************
    The candidate should complete the program provided, implementing
    the main.
    The program creates a child process; the child process reads
    from the keyboard an integer N >= 0, and transmits the values N, N-1, N-2, N-3, ..., 0
    (inclusive) to the parent process via a pipe.
    The father process reads from the pipe the values transmitted by the child process
    and prints them, until it receives the value 0; then the father process
    process waits for the termination of the child process and terminates.
    
    Example:
    I am the child process. Enter a number >=0: 4
    I am the father process. I have received: 4
    I am the father process. I have received: 3
    I am the father process. I have received: 2
    I am the father process. I have received: 1
    I am the father process. I have received: 0
    I am the father process. The son has finished.
    
******************************************************************/
    
    
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <unistd.h>
#include <sys/wait.h>
    
int main(int argc, char *argv[]) 
{
    
    int fd[2];
    int num, i;
    //Pipe creation
    if(pipe(fd)<0)
    {
        printf("Pipe creation failed\n");
        return 1;
    }
    //Creating a child process
    pid_t pid=fork();
    //Fork check
    if(pid<0)
    {
        printf("Fork failed\n");
        return 1;
    }
    //Entering the child process
    else if(pid==0){
        close (fd[0]);  // Not interested in reading
        printf("I am the child process\n");
        //Acquiring a number from input
        printf("Give me a number: ");
        scanf("%d", &num);
        //Sending the numbers trough a pipe
        for(i=num; i>=0; i--)
        {
            int sent=write(fd[1], &i, sizeof(num));
            //Check on the number of bytes the function wrote
            if(sent<0 || sent<sizeof(num))
            {
                printf("Error when sending\n");
                return 1;
            }
        }
        close (fd[1]);
        return 0;
    }
    //Entering the father process
    if(pid>0)
    {
        //Father process
        wait(NULL);
        close (fd[1]);// Not interested in writing
        for(i=4;i>=0;i--)//4 is a random number and it still works
        {
            int ricevuti=read(fd[0], &i, sizeof(num));
            //Check on the number of bytes the function read
            if(ricevuti<0 || ricevuti<(sizeof(num)))
            {
                printf("Error when receiving\n");
                return 1;
            }
            //Printing the values read by the function
            else
            {
                printf("I am the father process and i received: %d\n", i);
            }
        }
        printf("The child process has terminated\n");
    }
    close (fd[0]);
    return 0;
}

它适用于任何数字的原因是因为您正在从管道读取到 for 循环使用的迭代变量。因此,即使您在 i = 4 开始它,第一个 read(fd[0], &i, sizeof(num)) 也会将 i 更改为 child 发送的起始号码。

您应该阅读 num,而不是 i。父亲密码应该是:

    //Entering the father process
    if(pid>0)
    {
        //Father process
        wait(NULL);
        close (fd[1]);// Not interested in writing
        for(i=4;i>=0;i--)//4 is a random number and it still works
        {
            int ricevuti=read(fd[0], &num, sizeof(num));
            //Check on the number of bytes the function read
            if(ricevuti<0 || ricevuti<(sizeof(num)))
            {
                printf("Error when receiving\n");
                return 1;
            }
            //Printing the values read by the function
            else
            {
                printf("I am the father process and i received: %d\n", num);
            }
        }
        printf("The child process has terminated\n");
    }