Better Engineers

Better Engineers

Share this post

Better Engineers
Better Engineers
5 Common Ways of Inter-Process Communication (IPC) and How They Work

5 Common Ways of Inter-Process Communication (IPC) and How They Work

Better Engineering's avatar
Better Engineering
May 04, 2025
∙ Paid
21

Share this post

Better Engineers
Better Engineers
5 Common Ways of Inter-Process Communication (IPC) and How They Work
5
Share

What Is IPC?

Inter-Process Communication (IPC) is how two or more processes (programs) exchange data.
This is important because processes are isolated from each other by design.

Here are 5 major IPC methods:


1. Pipes

Pipes

  • Pipes are a simple form of shared memory that allows two processes to communicate with each other.

  • It is a half duplex method (or one way communication) used for IPC between two related processes .

  • One process writes data to the pipe, and the other process reads data from the pipe.

  • It is like a scenario like filling water with a tap into a bucket. The filling process is writing into the pipe and the reading process is retrieving from the pipe.

  • Pipes can be either named or anonymous, depending on whether they have a unique name or not.

  • Named pipes are a type of pipe that has a unique name and can be accessed by multiple processes. Named pipes can be used for communication between processes running on the same host or between processes running on different hosts over a network.

  • Anonymous pipes, on the other hand, are pipes that are created for communication between a parent process and its child process. Anonymous pipes are typically used for one-way communication between processes, as they do not have a unique name and can only be accessed by the processes that created them.

  • How it works:
    A pipe is a unidirectional communication channel.
    One process writes into the pipe, another reads from it.

  • Use case:
    Passing data from one process to another quickly on the same machine.

  • Example:
    In Linux, you can use the | operator:

    /* pipe.c */ #define STRING "Hello, world!" #define STRING_MAX 80
    int main (void) {
    /* Create pipe. */ int fd[2];
    pipe(fd);
    /* Create second process to communicate with. */
    int pid = fork();
    if (pid != 0) { /** Parent. **/ close(fd[0]); /* Close input. */
        write(fd[1], STRING, stren(STRING) +1);
        printf("Parent sent string: %s \n"', STRING) ;
    } 
    else i
    /** Child. **/
      close(fd[1]); /* Close output. */ char buff[STRING_MAX];
      read (fd[0], buff, STRING_MAX);
      printf("Child received string: %s\n", buff);
    }
    return 0;
    }
    
  • Notes:
    Pipes are usually anonymous (exist temporarily) but can also be named (FIFOs) for longer-term communication.


2. Message Queues

  • How it works:
    Processes send messages to a queue and other processes read messages from the queue.
    It's asynchronous — processes don’t have to be running at the same time.

  • Use case:
    Decoupling producers and consumers, buffering messages.

  • Example:

    • POSIX Message Queues

    • Systems like RabbitMQ or Kafka (at larger scales)

  • Notes:
    Great for handling bursts of communication without losing data.


3. Shared Memory

  • Shared memory is a region of memory that is accessible to multiple processes. This allows processes to communicate with each other by reading and writing data from the shared memory region.

  • Shared memory is a fast and efficient way for processes to communicate, but it can be difficult to use if the processes are not carefully synchronized.

  • There are two main types of shared memory:

    • Anonymous shared memory: Anonymous shared memory is not associated with any file or other system object. It is created by the operating system and is only accessible to the processes that created it.

    • Mapped shared memory: Mapped shared memory is associated with a file or other system object. It is created by mapping a file into the address space of one or more processes.

Multiple processes can access a common shared memory. Multiple processes communicate by shared memory, where one process makes changes at a time and then others view the change. Shared memory does not use kernel.

  • How it works:
    Processes map a part of memory into their address space together.
    They read and write into the same memory segment.

  • Use case:
    Super-fast communication — no copying data between processes.

  • Example:
    Using shmget, shmat, etc., in C on Linux.

  • Notes:
    Needs synchronization tools (like semaphores or mutexes) to avoid race conditions.


4. Sockets

With sockets, processes send and receive messages through the socket interface. The socket API supports send and recv operations that allow processes to send message buffers in and out of the kernel-level communication buffer.

Socket-based communication can happen between processes on different machines! If the process are on different machines, then the communication buffer is really between the process and the network device that will actually send the data.

  • How it works:
    Processes send data packets to each other over network-like connections — even if they are on the same machine.

  • Use case:
    Communicating between processes on different machines or different servers.

  • Example:

    • TCP/UDP sockets

    • UNIX Domain Sockets (for same-machine communication)

  • Notes:
    Sockets allow full-duplex communication (both sides can send/receive at the same time).


5. Signals

  • How it works:
    A signal is a limited way to notify a process that something happened.

  • Use case:
    Interrupting or controlling processes (like telling a process to stop, reload, or do something specific).

  • Example:

    • kill -SIGTERM <pid> — sends a termination signal.

    • SIGUSR1 — custom user-defined signal.

  • Notes:
    Signals are lightweight, but only carry very little information (basically just an interrupt).

    Example of Signal

    /* signal.c */
    int g_count = 0;
    void handle_signal (int sig) 
      if (sig == SIGINT)
      printf("Nya, nya, nya - I can't hear you! \n");
      if (sig == SIGHUP) {
      printf ("Resetting g_count to 0.\n");
      g_count = 0;
      }
    }
    int main() {
      struct sigaction handle_action;
      handle_action.sa_handler = handle_signal; /* handler */
      sigemptyset(&handle_action.sa_mask); /* clear set */
      handle_action.sa_flags = 0; /* no special mod to behavior */
    
      if (sigaction(SIGINT, &handle_action, NULL) == -1) 
         perror ("sigaction"); 
         return 1;
      if (sigaction(SIGHUP, &handle_action, NULL) == -1) 
         perror("sigaction"); 
         return 1;
    }
    while (1) {
     pause();
     printf("%d: Waiting for any signal ...\n", g_count++);
    }
     return 0; /* Will never get here.
    }

Test your knowledge

1. What is Inter-Process Communication (IPC) and why is it important?

Keep reading with a 7-day free trial

Subscribe to Better Engineers to keep reading this post and get 7 days of free access to the full post archives.

Already a paid subscriber? Sign in
© 2025 Dev Dhar
Privacy ∙ Terms ∙ Collection notice
Start writingGet the app
Substack is the home for great culture

Share