Using pipe to pass integer values between parent and child

前端 未结 1 1638
野趣味
野趣味 2020-11-29 02:11

I\'m a little confused on how to properly use pipe() to pass integer values between two processes.

In my program I first create a pipe, then I fork it. I assume I ha

相关标签:
1条回答
  • 2020-11-29 02:35

    This is about as lame (and no error checking, btw) a sample as I can muster for using a pipe to send int from a parent to a child process, where the child was launched from fork(). It gets more complicated (obviously) for sending and receiving data, but i can't do everything for you. This just forks and waits for an int (actually, the number of bytes that are used by an int) from the child.

    Update: Added send+response two-way communication example after this one. See the second code listing for more information.

    Hope it helps.

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    
    int main(int argc, char *argv[])
    {
        int fd[2];
        int val = 0;
    
        // create pipe descriptors
        pipe(fd);
    
        // fork() returns 0 for child process, child-pid for parent process.
        if (fork() != 0)
        {
            // parent: writing only, so close read-descriptor.
            close(fd[0]);
    
            // send the value on the write-descriptor.
            val = 100;
            write(fd[1], &val, sizeof(val));
            printf("Parent(%d) send value: %d\n", getpid(), val);
    
            // close the write descriptor
            close(fd[1]);
        }
        else
        {   // child: reading only, so close the write-descriptor
            close(fd[1]);
    
            // now read the data (will block)
            read(fd[0], &val, sizeof(val));
            printf("Child(%d) received value: %d\n", getpid(), val);
    
            // close the read-descriptor
            close(fd[0]);
        }
        return 0;
    }
    

    Output:

    Parent(5943) send value: 100
    Child(5945) received value: 100
    

    Update: Expanded to include send+response using two pipe sets

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/wait.h>
    
    // some macros to make the code more understandable
    //  regarding which pipe to use to a read/write operation
    //
    //  Parent: reads from P1_READ, writes on P1_WRITE
    //  Child:  reads from P2_READ, writes on P2_WRITE
    #define P1_READ     0
    #define P2_WRITE    1
    #define P2_READ     2
    #define P1_WRITE    3
    
    // the total number of pipe *pairs* we need
    #define NUM_PIPES   2
    
    int main(int argc, char *argv[])
    {
        int fd[2*NUM_PIPES];
        int val = 0, len, i;
        pid_t pid;
    
        // create all the descriptor pairs we need
        for (i=0; i<NUM_PIPES; ++i)
        {
            if (pipe(fd+(i*2)) < 0)
            {
                perror("Failed to allocate pipes");
                exit(EXIT_FAILURE);
            }
        }
    
        // fork() returns 0 for child process, child-pid for parent process.
        if ((pid = fork()) < 0)
        {
            perror("Failed to fork process");
            return EXIT_FAILURE;
        }
    
        // if the pid is zero, this is the child process
        if (pid == 0)
        {
            // Child. Start by closing descriptors we
            //  don't need in this process
            close(fd[P1_READ]);
            close(fd[P1_WRITE]);
    
            // used for output
            pid = getpid();
    
            // wait for parent to send us a value
            len = read(fd[P2_READ], &val, sizeof(val));
            if (len < 0)
            {
                perror("Child: Failed to read data from pipe");
                exit(EXIT_FAILURE);
            }
            else if (len == 0)
            {
                // not an error, but certainly unexpected
                fprintf(stderr, "Child: Read EOF from pipe");
            }
            else
            {
                // report what we received
                printf("Child(%d): Received %d\n", pid, val);
    
                // now double it and send it back
                val *= 2;
    
                printf("Child(%d): Sending %d back\n", pid, val);
                if (write(fd[P2_WRITE], &val, sizeof(val)) < 0)
                {
                    perror("Child: Failed to write response value");
                    exit(EXIT_FAILURE);
                }
            }
    
            // finished. close remaining descriptors.
            close(fd[P2_READ]);
            close(fd[P2_WRITE]);
    
            return EXIT_SUCCESS;
        }
    
        // Parent. close unneeded descriptors
        close(fd[P2_READ]);
        close(fd[P2_WRITE]);
    
        // used for output
        pid = getpid();
    
        // send a value to the child
        val = 42;
        printf("Parent(%d): Sending %d to child\n", pid, val);
        if (write(fd[P1_WRITE], &val, sizeof(val)) != sizeof(val))
        {
            perror("Parent: Failed to send value to child ");
            exit(EXIT_FAILURE);
        }
    
        // now wait for a response
        len = read(fd[P1_READ], &val, sizeof(val));
        if (len < 0)
        {
            perror("Parent: failed to read value from pipe");
            exit(EXIT_FAILURE);
        }
        else if (len == 0)
        {
            // not an error, but certainly unexpected
            fprintf(stderr, "Parent(%d): Read EOF from pipe", pid);
        }
        else
        {
            // report what we received
            printf("Parent(%d): Received %d\n", pid, val);
        }
    
        // close down remaining descriptors
        close(fd[P1_READ]);
        close(fd[P1_WRITE]);
    
        // wait for child termination
        wait(NULL);
    
        return EXIT_SUCCESS;
    }
    

    (compile with, e.g., gcc thisfile.c -o test)

    Output

    Parent(2794): Sending 42 to child
    Child(2797): Received 42
    Child(2797): Sending 84 back
    Parent(2794): Received 84
    
    0 讨论(0)
提交回复
热议问题