Inter Process Communications – Pipes Explained With Simple Example

Pipes are one of the oldest and simplest form of Inter-Process communications. Typically, a pipe is half-duplex way of transmitting data between two processes which means data can be passed in one direction only. It can be used only between processes having common parent.
Normally pipes are used between parent and child processes.

Properties

  • Pipes are half duplex.
  • Pipes can only be used having common parent.
  • Typically, pipes are used along with a process calling fork ().
  • If only one directional flow is needed the one process can close the write end whereas other process can close the read end of the pipe.
  • If read end of a pipe is closed and something written on the pipe, then SIGPIPE signal will be generated.

Example

Let’s look into a sample program to understand the Pipes usage and functionality. Before going ahead have a look into Exit handler and fork ().

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <sys/wait.h>

void exitHandler(void)
{
    printf(" Exiting process pid %d ppid %d \n", getpid(), getppid());
}

int main()
{
    int pfds[2];

    char buf[100];

    if(pipe(pfds) == -1)
    {
        perror("Pipe creation failed");
    }

    printf("Writing to fds %d \n", pfds[1]);
    write(pfds[1], "Hello World", 12);
    printf("Reading from fds %d \n", pfds[0]);
    read(pfds[0], buf, 12);
    printf("String read is [%s] \n", buf);

    printf("Testing pipes using fork \n");

    if(fork())
    {
        printf("Inside pid %d ppid %d \n", getpid(), getppid());
        printf("parent process will write only \n");
        close(pfds[0]);

        int count = 0;
        while(count < 5)
        {
            printf("Parent writing \n");
            write(pfds[1], "Parent sending", 15);
            sleep(5);
            count++;
        }
        printf("Parent exiting \n");
        wait(NULL);
        atexit(exitHandler);
    }
    else
    {
        printf("Inside pid %d ppid %d \n", getpid(), getppid());
        printf("child process will read only \n");
        close(pfds[1]);

        int count = 0;
        while(count < 5)
        {
            read(pfds[0], buf, 15);
            printf("string read at child is [%s] \n", buf);
            count++;
        }
        printf("child exiting \n");
        atexit(exitHandler);
        exit(0);
    }

    return 0;
}

Let’s look into the output of above program.

Writing to fds 4
Reading from fds 3
String read is [Hello World]
Testing pipes using fork
Inside pid 29948 ppid 1804
parent process will write only
Parent writing
Inside pid 29949 ppid 29948
child process will read only
string read at child is [Parent sending]
Parent writing
string read at child is [Parent sending]
Parent writing
string read at child is [Parent sending]
Parent writing
string read at child is [Parent sending]
Parent writing
string read at child is [Parent sending]
child exiting
 Exiting process pid 29949 ppid 29948
Parent exiting
 Exiting process pid 29948 ppid 1804

Leave a Reply

Your email address will not be published. Required fields are marked *