Operating Systems
Unit 9: Inter Process Communication (IPC)
Master how processes talk to each other â from shared memory and pipes to message queues â with complete C code examples and real-world Indian industry applications.
â±ïž Time to Complete: 6 hrs theory + 4 hrs lab | ð° Earning Potential: â¹8,000ââ¹20,000/month | ð 30 MCQs (Bloom's Mapped)
ðŒ Jobs this unlocks: Backend Engineer (â¹6â12 LPA) | Systems Programmer (â¹8â15 LPA)
Opening Hook â Indian Railways: The World's Largest IPC System
ð How Does Indian Railways Coordinate 13,000 Trains Every Day?
Picture New Delhi Railway Station at 8 AM. The station master needs to simultaneously communicate with the signal room (which track is free?), the loco pilot (reduce speed, platform 5 is ready), the ticket counter (Rajdhani Express is delayed by 20 minutes), and the platform announcer (announce the arrival on PA system). Each of these is a separate "process" â independent, running concurrently, with its own state and data.
The station master can't walk to each person individually. Instead, they use different communication mechanisms: a direct phone line to the signal room (like a pipe), a shared status board visible to everyone (like shared memory), an official memo sent through the system (like a message queue), and a broadcast announcement (like signals/events). This is Inter Process Communication (IPC) in real life.
Indian Railways runs 13,000+ trains daily, serving 23 million passengers, across 7,000+ stations. Their digital systems â CRIS (Centre for Railway Information Systems) â process millions of IPC operations per second: reservation updates, PNR status queries, signal coordination, and real-time tracking. Every time you check PNR status on IRCTC, multiple processes communicate behind the scenes to fetch your data.
Could YOU design this communication system? By the end of this unit, you'll know exactly how â using pipes, shared memory, message queues, and more. Let's build it.
Learning Outcomes â Bloom's Taxonomy Mapped
| Bloom's Level | Learning Outcome |
|---|---|
| ðµ Remember | List and define the major IPC mechanisms: pipes, named pipes, shared memory, message queues, and message passing |
| ðµ Understand | Explain how shared memory and message passing differ in terms of speed, synchronization, and use cases with Indian examples |
| ð¢ Apply | Write complete C programs using pipe(), mkfifo(), shmget(), and mq_open() for inter-process communication |
| ð¢ Analyze | Compare and contrast IPC mechanisms across dimensions of speed, directionality, persistence, and process relationship requirements |
| ð Evaluate | Evaluate which IPC mechanism is most appropriate for a given real-world scenario such as Indian Railways or Razorpay's payment system |
| ð Create | Design a multi-process communication system prototype using IPC primitives for a real-world Indian application |
Concept Explanation â Inter Process Communication from Scratch
1. IPC Need and Overview
In an operating system, processes are isolated by design â each has its own address space, its own stack, its own data. This isolation is great for security and stability (a crash in one process doesn't kill another). But real applications need processes to cooperate. A web server process needs to talk to a database process. A print spooler needs to accept jobs from multiple applications. A payment gateway needs its fraud-detection module to communicate with its transaction processor.
Why do processes need to communicate?
- Data sharing: Multiple processes working on the same dataset (e.g., IRCTC reservation + waitlist processes sharing seat data)
- Computation speedup: Divide a task among multiple processes and combine results
- Modularity: Break a large system into smaller, independent processes (microservices at Razorpay)
- Convenience: A user may run multiple tasks simultaneously â editor, compiler, browser â that need to share clipboard data
ð IPC Mechanisms â The Big Picture (Indian Railway Analogy)
Everyone can see and edit the same document simultaneously. Fast, but you need rules (synchronization) to avoid conflicts. Like a shared status board at the railway station that the station master, signal operator, and announcer all read and update.
Message Queue = Official Memo SystemStructured messages placed in an ordered queue. The sender writes a memo, drops it in the box; the receiver picks it up when ready. Like the official telegraph/message system between railway stations â messages are prioritized and processed in order.
Pipe = Walkie-TalkieDirect, real-time, one-direction communication between two people. The station master talks, the loco pilot listens. Simple and fast, but only works between people who know each other (related processes).
Named Pipe (FIFO) = Public Notice Board with a NameAny process can write to or read from it by name â even unrelated processes. Like a named notice board at the station that any department can use.
Message Passing = Formal Letter ExchangeProcesses explicitly send and receive messages. Can be synchronous (wait for reply) or asynchronous (send and continue). Like sending an official letter between railway zones â structured, traceable, but slower than a phone call.
2. Shared Memory (System V IPC)
Plain English: Imagine two roommates sharing a whiteboard in their room. Either roommate can write on it or read from it at any time â no messenger needed. It's the fastest way to exchange information because the data is just there, in a memory region accessible to both processes.
Technical Definition: Shared memory is a region of memory that is mapped into the address space of two or more processes. Once set up, processes can read and write to this memory directly, without any kernel intervention for data transfer. This makes it the fastest IPC mechanism.
Key System Calls
| Function | Purpose | Analogy |
|---|---|---|
shmget() | Create or get a shared memory segment | Buying the whiteboard |
shmat() | Attach the segment to process address space | Hanging the whiteboard in your room |
shmdt() | Detach the segment from process | Taking the whiteboard off the wall |
shmctl() | Control operations (destroy, get info) | Throwing away the whiteboard |
C Code â Shared Memory Writer Process
C /* shm_writer.c â Writes data to shared memory segment */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/ipc.h> #include <sys/shm.h> int main() { // Generate a unique key using ftok key_t key = ftok("shmfile", 65); // Create shared memory segment of 1024 bytes int shmid = shmget(key, 1024, 0666 | IPC_CREAT); if (shmid == -1) { perror("shmget failed"); return 1; } // Attach to shared memory char *str = (char *)shmat(shmid, NULL, 0); if (str == (char *)-1) { perror("shmat failed"); return 1; } // Write data to shared memory printf("Write data: "); fgets(str, 1024, stdin); printf("Data written to shared memory: %s\n", str); // Detach from shared memory shmdt(str); return 0; }
C Code â Shared Memory Reader Process
C /* shm_reader.c â Reads data from shared memory segment */ #include <stdio.h> #include <stdlib.h> #include <sys/ipc.h> #include <sys/shm.h> int main() { // Generate the SAME key as writer key_t key = ftok("shmfile", 65); // Get the existing shared memory segment int shmid = shmget(key, 1024, 0666); if (shmid == -1) { perror("shmget failed"); return 1; } // Attach to shared memory char *str = (char *)shmat(shmid, NULL, 0); if (str == (char *)-1) { perror("shmat failed"); return 1; } // Read data from shared memory printf("Data read from shared memory: %s\n", str); // Detach from shared memory shmdt(str); // Destroy the shared memory segment shmctl(shmid, IPC_RMID, NULL); return 0; }
Compilation & Execution
Bash # First, create the key file $ touch shmfile # Compile both programs $ gcc shm_writer.c -o shm_writer $ gcc shm_reader.c -o shm_reader # Run writer first (in Terminal 1) $ ./shm_writer # Run reader second (in Terminal 2) $ ./shm_reader
ipcs -m to see orphaned segments and ipcrm -m <shmid> to clean them up. Leaked shared memory is a common issue in production systems.
3. Message Passing
Plain English: Instead of sharing a whiteboard, imagine two people exchanging letters. The sender writes a message, puts it in an envelope, and sends it. The receiver opens the envelope and reads it. There's no shared space â the message is copied from sender to receiver through the kernel.
Technical Definition: Message passing is an IPC mechanism where processes communicate by explicitly sending and receiving messages through the operating system kernel. The kernel manages the message buffer and ensures delivery.
ðš Direct vs Indirect Communication
Processes must name each other explicitly. send(P, message) sends to process P. receive(Q, message) receives from process Q. Like calling someone directly on their phone â you must know their number. A link is established automatically between exactly two processes.
Messages are sent to and received from mailboxes (also called ports). send(A, message) sends to mailbox A. receive(A, message) receives from mailbox A. Like dropping a letter in a post office box â anyone with the box key can read it. Multiple processes can share a mailbox.
â±ïž Synchronous vs Asynchronous Message Passing
Blocking send: The sender is blocked until the message is received by the receiver. Like making a phone call â you wait until the other person picks up.
Blocking receive: The receiver blocks until a message is available. Like waiting at the door for the postman.
Asynchronous (Non-blocking)Non-blocking send: The sender sends the message and continues immediately. Like sending a WhatsApp message â you don't wait for "blue ticks."
Non-blocking receive: The receiver either gets a valid message or a null/empty indication. Like checking your mailbox â if there's no letter, you move on.
| Feature | Direct Communication | Indirect Communication |
|---|---|---|
| Naming | Must know exact process ID | Uses shared mailbox/port |
| Coupling | Tightly coupled | Loosely coupled |
| Flexibility | One-to-one only | Many-to-many possible |
| Analogy | Direct phone call | Post office box |
| Use Case | Parent-child process communication | Server handling multiple client requests |
4. Pipes (Unnamed Pipes)
Plain English: A pipe is like a water pipe â data flows in one direction. One process pours data in at one end, another process drinks from the other end. It's the simplest IPC mechanism in Unix/Linux.
Technical Definition: A pipe is a unidirectional communication channel that connects the standard output of one process to the standard input of another. It uses two file descriptors: fd[0] for reading and fd[1] for writing.
How pipe() Works
C int fd[2]; pipe(fd); // fd[0] = read end (mouth of the pipe â drink from here) // fd[1] = write end (top of the pipe â pour data here)
C Code â Parent Writes, Child Reads via Pipe
C /* pipe_demo.c â Parent sends message to child via pipe */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/wait.h> int main() { int fd[2]; // fd[0]=read, fd[1]=write pid_t pid; char write_msg[] = "Train 12301 Rajdhani: Platform 5 Ready!"; char read_msg[100]; // Create the pipe if (pipe(fd) == -1) { perror("Pipe creation failed"); return 1; } pid = fork(); // Create child process if (pid < 0) { perror("Fork failed"); return 1; } if (pid > 0) { // ===== PARENT PROCESS (Station Master) ===== close(fd[0]); // Close unused read end printf("[Station Master] Sending: %s\n", write_msg); write(fd[1], write_msg, strlen(write_msg) + 1); close(fd[1]); // Close write end after writing wait(NULL); // Wait for child to finish } else { // ===== CHILD PROCESS (Platform Announcer) ===== close(fd[1]); // Close unused write end read(fd[0], read_msg, sizeof(read_msg)); printf("[Announcer] Received: %s\n", read_msg); printf("[Announcer] ð¢ Attention passengers...\n"); close(fd[0]); // Close read end } return 0; }
Shell Pipe Operator |
The shell pipe operator | is the most common use of unnamed pipes. When you type:
Bash $ ls -l | grep ".c" | wc -l
The shell creates two pipes:
- Pipe 1: Connects
ls -l(stdout) âgrep ".c"(stdin). Lists all files, grep filters only .c files. - Pipe 2: Connects
grep ".c"(stdout) âwc -l(stdin). Counts the number of .c files.
Result: You get the count of C source files in the current directory. Three processes, two pipes, zero temporary files.
| symbol was chosen because it looks like a pipe connecting two things. This single invention shaped the entire Unix philosophy of "small tools that do one thing well, connected by pipes."
Limitations of Unnamed Pipes
| Limitation | Explanation |
|---|---|
| Unidirectional | Data flows in only one direction. For two-way communication, you need two pipes. |
| Related processes only | Only works between parent-child or sibling processes (created by fork). Unrelated processes cannot use unnamed pipes. |
| No persistence | The pipe exists only as long as both processes are alive. No file on disk. |
| Limited capacity | Pipes have a kernel buffer limit (typically 64 KB on Linux). Writing beyond this blocks the writer. |
5. Named Pipes (FIFOs)
Plain English: A named pipe is like a pipe with a name tag on it, placed in a public area. Any process â not just parent-child â can use it, as long as they know the name. It appears as a special file in the filesystem.
Technical Definition: A FIFO (First In, First Out) is a special type of file that provides a named, persistent pipe. Unlike unnamed pipes, FIFOs have a name in the filesystem and can be used by unrelated processes. Created with the mkfifo() system call or the mkfifo command.
C Code â FIFO Writer (Unrelated Process 1)
C /* fifo_writer.c â Writes to a named pipe (FIFO) */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <fcntl.h> #include <sys/stat.h> #include <unistd.h> int main() { char *fifo_path = "/tmp/railway_fifo"; char message[256]; // Create the FIFO (named pipe) if it doesn't exist mkfifo(fifo_path, 0666); printf("[Signal Room] FIFO Writer ready. Type messages:\n"); // Open FIFO for writing int fd = open(fifo_path, O_WRONLY); printf("Enter message: "); fgets(message, 256, stdin); write(fd, message, strlen(message) + 1); printf("[Signal Room] Message sent: %s", message); close(fd); return 0; }
C Code â FIFO Reader (Unrelated Process 2)
C /* fifo_reader.c â Reads from a named pipe (FIFO) */ #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <sys/stat.h> #include <unistd.h> int main() { char *fifo_path = "/tmp/railway_fifo"; char buffer[256]; // Open FIFO for reading (blocks until writer opens it) printf("[Station Master] Waiting for signal room message...\n"); int fd = open(fifo_path, O_RDONLY); read(fd, buffer, 256); printf("[Station Master] Received: %s", buffer); close(fd); // Remove the FIFO file unlink(fifo_path); return 0; }
Compilation & Execution
Bash $ gcc fifo_writer.c -o fifo_writer $ gcc fifo_reader.c -o fifo_reader # Terminal 1: Start the reader first (it will block waiting) $ ./fifo_reader [Station Master] Waiting for signal room message... # Terminal 2: Start the writer $ ./fifo_writer [Signal Room] FIFO Writer ready. Type messages: Enter message: Track 3 clear for departure [Signal Room] Message sent: Track 3 clear for departure # Back in Terminal 1: [Station Master] Received: Track 3 clear for departure
Unnamed Pipes vs Named Pipes (FIFOs)
| Feature | Unnamed Pipe | Named Pipe (FIFO) |
|---|---|---|
| Created by | pipe() system call | mkfifo() or mkfifo command |
| Filesystem presence | No file â exists only in kernel | Yes â appears as a special file |
| Process relationship | Only related (parent-child) | Any processes (related or unrelated) |
| Persistence | Destroyed when processes exit | Persists until explicitly deleted (unlink) |
| Direction | Unidirectional | Unidirectional (but can open two FIFOs for bidirectional) |
| Naming | No name â identified by file descriptors | Has a pathname in the filesystem |
| Use case | Shell commands: ls | grep | Client-server communication, logging |
6. popen() and pclose()
Plain English: popen() is a convenience function that does three things in one call: creates a pipe, forks a child process, and execs a shell command. It's like having a helper who runs a command for you and hands you the output through a pipe. pclose() waits for the command to finish and cleans up.
Technical Definition: popen() opens a process by creating a pipe, forking, and invoking the shell. It returns a FILE pointer that can be used for reading (capturing command output) or writing (sending input to command).
C Code â Using popen() to Capture Command Output
C /* popen_demo.c â Execute a command and read its output */ #include <stdio.h> #include <stdlib.h> int main() { FILE *fp; char buffer[256]; printf("=== System Information via popen() ===\n\n"); // Execute "uname -a" and read output fp = popen("uname -a", "r"); if (fp == NULL) { perror("popen failed"); return 1; } printf("OS Info: "); while (fgets(buffer, sizeof(buffer), fp) != NULL) { printf("%s", buffer); } pclose(fp); // Execute "ls -la *.c" and read output fp = popen("ls -la *.c 2>/dev/null", "r"); if (fp != NULL) { printf("\nC source files:\n"); while (fgets(buffer, sizeof(buffer), fp) != NULL) { printf(" %s", buffer); } pclose(fp); } // Execute "date" to get current time fp = popen("date", "r"); if (fp != NULL) { printf("\nCurrent time: "); fgets(buffer, sizeof(buffer), fp); printf("%s", buffer); pclose(fp); } return 0; }
/bin/sh), so it's vulnerable to shell injection attacks if you pass unsanitized user input. Never do popen(user_input, "r") in production code.
7. Message Queues (POSIX)
Plain English: A message queue is like a post office box system. Process A drops a letter (message) into a specific numbered box. Process B opens that box and picks up the letter whenever it's ready. Messages have priorities â urgent telegrams get picked up before regular letters.
Technical Definition: POSIX message queues provide a prioritized, asynchronous messaging mechanism between processes. Messages are stored in the kernel and can be retrieved by priority. Unlike pipes, message queues preserve message boundaries â each message is an independent unit.
Key System Calls
| Function | Purpose | Analogy |
|---|---|---|
mq_open() | Create or open a message queue | Getting a post office box |
mq_send() | Send a message to the queue | Dropping a letter in the box |
mq_receive() | Receive a message from the queue | Picking up a letter from the box |
mq_close() | Close the message queue descriptor | Walking away from the post office |
mq_unlink() | Remove the message queue | Cancelling the post office box |
C Code â Message Queue Sender
C /* mq_sender.c â Sends messages to a POSIX message queue */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <mqueue.h> #include <fcntl.h> #include <sys/stat.h> #define QUEUE_NAME "/railway_queue" #define MAX_SIZE 1024 #define MSG_STOP "exit" int main() { mqd_t mq; char buffer[MAX_SIZE]; // Set queue attributes struct mq_attr attr; attr.mq_flags = 0; attr.mq_maxmsg = 10; // Max 10 messages in queue attr.mq_msgsize = MAX_SIZE; // Max message size attr.mq_curmsgs = 0; // Create the message queue mq = mq_open(QUEUE_NAME, O_CREAT | O_WRONLY, 0644, &attr); if (mq == (mqd_t)-1) { perror("mq_open failed"); return 1; } printf("[Ticket Counter] Message Queue Sender ready.\n"); printf("Type messages (type 'exit' to quit):\n\n"); do { printf("Send> "); fgets(buffer, MAX_SIZE, stdin); buffer[strcspn(buffer, "\n")] = 0; // Remove newline // Send with priority 0 if (mq_send(mq, buffer, strlen(buffer) + 1, 0) == -1) { perror("mq_send failed"); } } while (strcmp(buffer, MSG_STOP) != 0); // Cleanup mq_close(mq); printf("[Ticket Counter] Sender closed.\n"); return 0; }
C Code â Message Queue Receiver
C /* mq_receiver.c â Receives messages from a POSIX message queue */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <mqueue.h> #include <fcntl.h> #define QUEUE_NAME "/railway_queue" #define MAX_SIZE 1024 #define MSG_STOP "exit" int main() { mqd_t mq; char buffer[MAX_SIZE + 1]; unsigned int priority; ssize_t bytes_read; // Open existing message queue for reading mq = mq_open(QUEUE_NAME, O_RDONLY); if (mq == (mqd_t)-1) { perror("mq_open failed"); return 1; } printf("[Display Board] Receiver ready. Waiting for messages...\n\n"); do { bytes_read = mq_receive(mq, buffer, MAX_SIZE + 1, &priority); if (bytes_read >= 0) { buffer[bytes_read] = '\0'; printf("Recv [priority=%u]: %s\n", priority, buffer); } } while (strcmp(buffer, MSG_STOP) != 0); // Cleanup mq_close(mq); mq_unlink(QUEUE_NAME); printf("\n[Display Board] Queue removed. Receiver closed.\n"); return 0; }
Compilation & Execution
Bash # Note: POSIX message queues need -lrt flag $ gcc mq_sender.c -o mq_sender -lrt $ gcc mq_receiver.c -o mq_receiver -lrt # Terminal 1: Start receiver $ ./mq_receiver # Terminal 2: Start sender $ ./mq_sender
mq_send(mq, buffer, len, priority), higher priority numbers get retrieved first by mq_receive(). In a railway system, "EMERGENCY: Track fault" (priority 9) would be retrieved before "Tea stall closed" (priority 1). This makes message queues ideal for systems where some messages are more urgent than others.
8. IPC Mechanism Comparison Table
| Feature | Shared Memory | Message Passing | Pipe | Named Pipe (FIFO) | Message Queue |
|---|---|---|---|---|---|
| Speed | â¡ Fastest (no kernel copy) | Moderate (kernel involvement) | Fast | Fast | Moderate |
| Direction | Bidirectional | Bidirectional | Unidirectional | Unidirectional | Bidirectional |
| Process Relationship | Any (related/unrelated) | Any | Related only (parent-child) | Any (related/unrelated) | Any (related/unrelated) |
| Persistence | Until explicitly destroyed | Until consumed | No â dies with processes | Filesystem file (persistent) | Until explicitly destroyed |
| Synchronization | â ïž Manual (semaphores needed) | Built-in (kernel manages) | Built-in (blocking read/write) | Built-in (blocking read/write) | Built-in (blocking + priority) |
| Message Boundaries | No (byte stream) | Yes (discrete messages) | No (byte stream) | No (byte stream) | Yes (discrete messages) |
| Complexity | High (sync + setup) | Moderate | Low | Low-Medium | Medium |
| Best Use Case | High-speed large data transfer (video, databases) | Distributed systems, microservices | Shell commands, simple parent-child | Client-server, logging | Task queues, priority messaging |
| Indian Example | IRCTC seat availability (shared across queries) | UPI payment verification chain | ls | grep in terminal | Log aggregation at Flipkart | Razorpay payment processing queue |
9. IPC in Modern Systems
The IPC mechanisms we studied (pipes, shared memory, message queues) are low-level, OS-provided primitives. In modern production systems, they've evolved into high-level abstractions:
| Low-Level IPC | Modern Equivalent | Used By |
|---|---|---|
| Message Queue | RabbitMQ, Apache Kafka, Amazon SQS | Razorpay, Swiggy, Netflix |
| Shared Memory | Redis (in-memory data store), Memcached | Flipkart, Instagram, Twitter |
| Message Passing | gRPC, REST APIs, GraphQL | Google, PhonePe, Uber |
| Pipes | Unix domain sockets, streaming APIs | Docker, Kubernetes, Nginx |
| Named Pipes | WebSockets, Server-Sent Events | Slack, Discord, real-time dashboards |
Microservices = High-Level IPC
In a microservices architecture, each service is essentially a separate process. The Payment Service at Razorpay needs to talk to the Fraud Detection Service, which needs to talk to the Bank Gateway Service, which needs to talk to the Notification Service. This is IPC at scale â across machines, across data centres, across continents.
1. API Gateway receives your payment request (REST API = message passing)
2. Request is pushed to Kafka message queue (message queue IPC)
3. Payment Processor picks it from queue, validates merchant (service-to-service gRPC = message passing)
4. Fraud Detection Service checks transaction patterns using Redis cache (shared memory equivalent)
5. Bank Gateway sends request to NPCI/bank via API (message passing)
6. Response flows back through the same chain
7. Notification Service sends SMS/email via queue (message queue IPC)
Total time: ~2 seconds. Total IPC calls: ~12. All happening concurrently across distributed systems. Every concept you learned in this unit is used here.
Learn by Doing â 3-Tier Lab Structure
ð¢ Tier 1 â GUIDED TASK: Pipe & FIFO Communication in C
Part A: Unnamed Pipe â Parent-Child Communication
Step 1: Create the Source File
Open a terminal and create a new file:
Bash
$ mkdir -p ~/ipc_labs && cd ~/ipc_labs
$ nano pipe_lab.c
Step 2: Type the Complete Code
C /* pipe_lab.c â Bidirectional parent-child communication */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/wait.h> int main() { int pipe1[2]; // Parent â Child int pipe2[2]; // Child â Parent pid_t pid; char parent_msg[] = "Station Master: Is Platform 3 clear?"; char child_msg[] = "Signal Room: Yes, Platform 3 is clear!"; char buffer[256]; // Create both pipes if (pipe(pipe1) == -1 || pipe(pipe2) == -1) { perror("Pipe creation failed"); return 1; } pid = fork(); if (pid > 0) { // PARENT (Station Master) close(pipe1[0]); // Close read end of pipe1 close(pipe2[1]); // Close write end of pipe2 // Send question to child write(pipe1[1], parent_msg, strlen(parent_msg) + 1); printf("[Parent] Sent: %s\n", parent_msg); // Read reply from child read(pipe2[0], buffer, 256); printf("[Parent] Received reply: %s\n", buffer); close(pipe1[1]); close(pipe2[0]); wait(NULL); } else { // CHILD (Signal Room) close(pipe1[1]); // Close write end of pipe1 close(pipe2[0]); // Close read end of pipe2 // Read question from parent read(pipe1[0], buffer, 256); printf("[Child] Received: %s\n", buffer); // Send reply to parent write(pipe2[1], child_msg, strlen(child_msg) + 1); printf("[Child] Sent reply: %s\n", child_msg); close(pipe1[0]); close(pipe2[1]); } return 0; }
Step 3: Compile and Run
Bash
$ gcc pipe_lab.c -o pipe_lab
$ ./pipe_lab
Part B: Named Pipe (FIFO) â Two Unrelated Processes
Step 4: Create FIFO Writer
C /* fifo_lab_writer.c */ #include <stdio.h> #include <string.h> #include <fcntl.h> #include <sys/stat.h> #include <unistd.h> int main() { char *fifo = "/tmp/ipc_lab_fifo"; char msg[200]; mkfifo(fifo, 0666); printf("[Writer] Opening FIFO for writing...\n"); int fd = open(fifo, O_WRONLY); printf("Enter train announcement: "); fgets(msg, 200, stdin); write(fd, msg, strlen(msg) + 1); printf("[Writer] Sent!\n"); close(fd); return 0; }
Step 5: Create FIFO Reader
C /* fifo_lab_reader.c */ #include <stdio.h> #include <fcntl.h> #include <unistd.h> int main() { char *fifo = "/tmp/ipc_lab_fifo"; char buf[200]; printf("[Reader] Waiting for announcement...\n"); int fd = open(fifo, O_RDONLY); read(fd, buf, 200); printf("[Reader] Announcement: %s", buf); close(fd); unlink(fifo); return 0; }
Step 6: Compile and Run in Two Terminals
Bash $ gcc fifo_lab_writer.c -o fifo_writer $ gcc fifo_lab_reader.c -o fifo_reader # Terminal 1: $ ./fifo_reader # Terminal 2: $ ./fifo_writer
ð Congratulations! You've built both pipe and FIFO communication systems. Take screenshots â these are portfolio-worthy lab programs.
ð¡ Tier 2 â SEMI-GUIDED TASK: POSIX Shared Memory Writer + Reader
Your Mission:
Create two separate C programs that communicate using System V shared memory. The writer stores a struct containing train information; the reader displays it.
Hints:
- Define a struct: Create
struct TrainInfo { int train_no; char name[50]; char platform[10]; char status[20]; } - Writer program:
- Use
ftok()with a common key file - Use
shmget()withsizeof(struct TrainInfo) - Use
shmat()to get a pointer - Cast the pointer:
struct TrainInfo *train = (struct TrainInfo *)shmat(...) - Fill in train details and detach with
shmdt()
- Use
- Reader program:
- Use the same
ftok()key - Attach to existing segment (no IPC_CREAT flag)
- Read and print the struct fields
- Detach and destroy with
shmctl(shmid, IPC_RMID, NULL)
- Use the same
- Compile:
gcc shm_train_writer.c -o shm_writerandgcc shm_train_reader.c -o shm_reader - Key file: Remember to
touch shmfilefirst!
ready flag to the struct. The writer sets ready = 1 after writing. The reader busy-waits until ready == 1 before reading. This simulates basic synchronization without semaphores.
ðŽ Tier 3 â OPEN CHALLENGE: Python Multi-Process Chat System
Part A: Quick Start â Python multiprocessing.Queue
Python # queue_demo.py â Basic multiprocessing Queue demo from multiprocessing import Process, Queue import time def sender(q): messages = ["Train arriving", "Platform clear", "Departure in 5 min"] for msg in messages: print(f"[Sender] Sending: {msg}") q.put(msg) time.sleep(1) q.put("STOP") def receiver(q): while True: msg = q.get() if msg == "STOP": break print(f"[Receiver] Got: {msg}") if __name__ == "__main__": q = Queue() p1 = Process(target=sender, args=(q,)) p2 = Process(target=receiver, args=(q,)) p1.start() p2.start() p1.join() p2.join() print("Done!")
Part B: The Challenge â Build a Mini Chat System
Build a terminal-based chat system where two processes communicate via multiprocessing.Queue:
- Two processes: "Station Master" and "Signal Room"
- Two queues: One for each direction (bidirectional communication)
- Interactive input: Each process should accept user input and send it to the other
- Timestamps: Add timestamps to each message
- Graceful exit: Typing "quit" should end both processes
Deliverable: A working Python chat system. This demonstrates real IPC using Python's multiprocessing module.
Industry Spotlight â A Day in the Life
ð©âð» Priya Mehta, 27 â Backend Engineer at Razorpay, Pune
Background: B.Tech Computer Science from Savitribai Phule Pune University. Learned C and Linux systems programming in 3rd year. Built a multi-process chat application as a mini-project using pipes and shared memory. Interned at a Pune-based fintech startup where she worked on message queue systems. Joined Razorpay through their hiring challenge.
A Typical Day:
9:30 AM â Morning standup with the Payment Processing team. Discuss yesterday's Kafka consumer lag â some payment notifications were delayed by 3 seconds.
10:00 AM â Debug a race condition in the shared cache (Redis) where two payment processes were reading stale data. The fix? Implement distributed locking using Redis SETNX â directly inspired by semaphore concepts from OS class.
11:30 AM â Design a new gRPC service for merchant onboarding. Define protobuf message schemas â essentially message passing with strongly-typed messages.
1:00 PM â Lunch with the team. Discuss how to handle the upcoming IPL season traffic â 10x normal payment volume. Need to scale Kafka partitions.
2:30 PM â Write integration tests for the payment retry queue. When a bank API times out, the payment is pushed to a retry message queue with exponential backoff.
4:00 PM â Code review a junior engineer's pull request on the notification service. Their code wasn't properly closing message queue connections â classic resource leak.
5:30 PM â Learning hour â studying the internals of Apache Kafka's log-structured message storage. Understanding how it achieves 2M messages/second.
| Detail | Info |
|---|---|
| Tools Used Daily | Go, Kafka, gRPC, Redis, PostgreSQL, Docker, Kubernetes, Git |
| IPC Concepts Used | Message queues (Kafka), shared memory (Redis), message passing (gRPC), pipes (Unix domain sockets) |
| Entry Salary (2024) | â¹6â12 LPA + ESOPs |
| Mid-Level (3â5 yrs) | â¹15â25 LPA |
| Senior (7+ yrs) | â¹30â55 LPA |
| Companies Hiring | Razorpay, PhonePe, Zerodha, CRED, Paytm, Flipkart, Google India, Amazon India, Atlassian |
Earn With It â Freelance & Income Roadmap
ð° Your Earning Path After This Unit
Portfolio Piece: "Multi-Process Communication System in C" â a GitHub repo with working pipe, FIFO, shared memory, and message queue programs + a Python chat system.
Earning Ideas:
⢠Build IPC-based backend prototypes for early-stage startups â â¹8,000ââ¹15,000/project
⢠Create microservice communication demos for college tech fests â â¹3,000ââ¹8,000
⢠Write technical blog posts explaining IPC concepts â â¹2,000ââ¹5,000/article on Medium/GeeksforGeeks
⢠Develop inter-process automation scripts for small IT firms â â¹5,000ââ¹20,000/project
| Platform | Best For | Typical Rate |
|---|---|---|
| Toptal / Upwork | Backend engineering projects (IPC, messaging) | $25â$60/hour |
| Internshala | Indian startup backend internships | â¹8,000ââ¹20,000/month |
| Fiverr | Quick C/Linux system programming gigs | $20â$100/gig |
| Direct outreach to Indian fintech startups | â¹10,000ââ¹25,000/project | |
| GitHub + Blog | Build reputation â attract offers | Indirect â leads to job offers |
â±ïž Time to First Earning: 3â4 weeks (if you complete all 3 lab tiers and build a GitHub portfolio)
MCQ Assessment Bank â 30 Questions (Bloom's Mapped)
Remember / Identify (Q1âQ5)
Which system call is used to create an unnamed pipe in C?
- mkfifo()
- pipe()
- socket()
- mq_open()
In shared memory IPC, which function attaches a shared memory segment to the process address space?
- shmget()
- shmctl()
- shmat()
- shmdt()
FIFO in named pipes stands for:
- File Input/File Output
- First In First Out
- Fast Inter-process File Operation
- Filesystem IPC Function Object
Which of the following is NOT an IPC mechanism?
- Shared Memory
- Message Queue
- Thread Pool
- Named Pipe
The popen() function in C combines which three operations?
- open(), read(), close()
- pipe(), fork(), exec()
- socket(), bind(), listen()
- malloc(), write(), free()
Understand / Explain (Q6âQ10)
Why does shared memory require external synchronization (like semaphores) while pipes do not?
- Shared memory is slower than pipes
- Pipes are bidirectional while shared memory is unidirectional
- Shared memory allows simultaneous read/write access without built-in blocking, creating race conditions
- Semaphores are part of the shared memory API
What is the key difference between direct and indirect message passing?
- Direct is faster than indirect
- In direct communication, processes must name each other; in indirect, they communicate through a shared mailbox
- Direct supports multiple receivers; indirect supports only one
- Indirect message passing uses shared memory internally
Why can unnamed pipes only be used between related processes (parent-child)?
- The kernel restricts pipe access to the same user
- Unnamed pipes have no filesystem path; file descriptors are only inherited via fork()
- Unnamed pipes are too slow for unrelated processes
- The pipe() system call requires a parent PID as argument
In the context of message queues, what does "message boundary preservation" mean?
- Messages cannot exceed 1 KB
- Each message sent is received as a complete, discrete unit â not split or merged with other messages
- Messages are encrypted at the boundary between processes
- Only the sender can delete messages from the queue
What happens when a process tries to read from an empty pipe (with no data and at least one writer still open)?
- It returns an error immediately
- It returns 0 bytes
- It blocks (waits) until data becomes available
- The process is terminated by the kernel
Apply / Implement (Q11âQ15)
A process calls pipe(fd) and then fork(). The parent wants to send data to the child. Which file descriptors should the parent close?
- fd[0] and fd[1]
- fd[1] only
- fd[0] only (the read end)
- Neither â keep both open
You need two unrelated processes running on the same machine to exchange data. Which IPC mechanism would you use?
- Unnamed pipe
- Named pipe (FIFO) or Message Queue
- fork() with shared variables
- Thread synchronization
What is the correct compilation command for a C program using POSIX message queues?
gcc mq_prog.c -o mq_proggcc mq_prog.c -o mq_prog -lpthreadgcc mq_prog.c -o mq_prog -lrtgcc mq_prog.c -o mq_prog -lmq
In the shell command cat file.txt | grep "error" | wc -l, how many pipes are created?
- 1
- 2
- 3
- 0
You called shmget() to create a shared memory segment but forgot to call shmctl(shmid, IPC_RMID, NULL). What happens after your program exits?
- The segment is automatically destroyed
- The segment persists in kernel memory until the system reboots or is manually removed
- The kernel throws an error on next boot
- Other processes can no longer access shared memory
Analyze / Compare (Q16âQ20)
A high-frequency trading system needs to share price data between a data feed process and 10 analysis processes with minimal latency. Which IPC mechanism is most appropriate?
- Named Pipes (one for each analysis process)
- Shared Memory with read-write locks
- POSIX Message Queues
- popen() calls
Why might a developer choose message queues over shared memory for an e-commerce order processing system?
- Message queues are always faster
- Message queues provide automatic ordering, priority, and persistence without manual synchronization
- Shared memory cannot handle more than 2 processes
- Message queues use less kernel memory
Comparing pipes and message queues: which statement is true?
- Pipes preserve message boundaries; message queues do not
- Both pipes and message queues are unidirectional only
- Pipes are byte streams; message queues preserve discrete messages
- Message queues only work between related processes
In a microservice architecture, which low-level IPC concept is most closely analogous to Apache Kafka?
- Unnamed Pipe
- Shared Memory
- Message Queue
- Semaphore
A Named Pipe (FIFO) file shows a size of 0 bytes on disk even while processes are actively communicating through it. Why?
- The filesystem driver has a bug
- FIFOs store data in kernel buffers, not on disk â the filesystem entry is just a reference point
- The data is compressed to zero size
- Named pipes can only transfer empty signals, not data
Evaluate / Justify (Q21âQ25)
A startup's payment system uses shared memory (without semaphores) for communication between the payment processor and fraud detection service. After launch, they notice occasional corrupted transaction data. What is the most likely cause?
- Shared memory segment is too small
- The ftok() key is generating collisions
- Race condition: both processes read/write shared memory simultaneously without synchronization
- The operating system doesn't support shared memory for financial applications
An IRCTC architect proposes using unnamed pipes for communication between the web server process and the database process. Evaluate this decision.
- Good choice â pipes are fast and simple
- Bad choice â the web server and database are typically unrelated processes that cannot share pipe file descriptors
- Good choice â pipes work for all process types
- Bad choice â pipes don't work on Linux servers
A team switches from synchronous message passing to asynchronous message passing in their IPC design. What trade-off do they make?
- Lower throughput but guaranteed delivery
- Higher throughput and responsiveness but need to handle out-of-order delivery and buffer management
- No trade-off â asynchronous is always better
- Asynchronous message passing is slower but more secure
Which IPC mechanism would you recommend for a logging service where multiple application processes need to write log entries to a central logger process?
- Shared memory â fastest option
- Unnamed pipes â simplest option
- Named pipe (FIFO) or message queue â supports multiple unrelated writers to one reader
- popen() â easiest to implement
A system uses message queues with priorities for a hospital emergency system. Emergency cases get priority 9, routine cases get priority 1. Why is this better than a simple FIFO pipe?
- Message queues are faster than pipes
- Pipes cannot transfer structured data
- Message queues allow urgent messages to be retrieved first regardless of arrival order, potentially saving lives
- Pipes crash when handling medical data
Create / Design (Q26âQ30)
You're designing a system where Process A generates video frames, Process B applies filters, and Process C displays the result. All on the same machine. What IPC design would you use?
- Three unnamed pipes in a pipeline: A â pipe â B â pipe â C
- Shared memory with A writing frames, B reading + processing + writing filtered frames, C reading filtered frames
- Message queues for all communication
- Named pipes with three separate FIFOs
Design an IPC system for an ATM machine. The ATM software has separate processes for: card reader, PIN verification, balance inquiry, cash dispensing, and receipt printing. Which IPC architecture would you choose?
- A central message queue where all processes send/receive messages
- Unnamed pipes connecting each process to the next in sequence
- Shared memory for all processes with no synchronization
- Each process writes to a separate log file
You need to build a real-time stock ticker that receives price updates from an exchange process and distributes them to 50 client display processes. What combination of IPC would you design?
- 50 separate unnamed pipes â one for each client
- Shared memory for price data + semaphores for synchronization + signals for update notifications
- 50 message queues â one for each client
- Named pipes with round-robin reading
Design a producer-consumer system where 3 producer processes generate sensor data and 2 consumer processes analyze it. Data must not be lost even if a consumer crashes. Which IPC design is best?
- Unnamed pipes from each producer to each consumer
- Shared memory with a circular buffer
- Persistent message queue with acknowledgement â consumers confirm processing before messages are removed
- Named pipes with multiple readers
You're tasked with designing the IPC architecture for Indian Railways' next-generation station management system. The system needs: real-time train tracking (high speed), passenger announcements (broadcast), ticket booking updates (persistent, ordered), and emergency alerts (highest priority). Which combination of IPC mechanisms would you architect?
- Shared memory for everything â it's the fastest
- Shared memory for tracking + message queue with priorities for emergencies + named pipe for announcements + persistent message queue for bookings
- Message queues for everything â they're the most versatile
- Pipes for everything â they're the simplest
Short Answer Questions
Q1: Explain the difference between shared memory and message passing IPC. When would you use each?
Shared Memory: A common memory region is mapped into multiple processes' address spaces. Processes read/write directly to this memory without kernel involvement for data transfer. It's the fastest IPC method but requires explicit synchronization (semaphores/mutexes) to prevent race conditions.
Message Passing: Processes communicate by explicitly sending and receiving messages through the kernel. The kernel copies data from sender's buffer to receiver's buffer. It's slower than shared memory but provides built-in synchronization and message boundaries.
Use Shared Memory when: High-speed, large data transfer is needed (video processing, real-time databases, shared caches). Example: IRCTC's seat availability data shared across multiple query processes.
Use Message Passing when: You need structured, ordered, priority-based communication between loosely coupled processes. Example: UPI payment processing where each step sends a message to the next service.
Q2: What are the four key system calls for System V shared memory? Explain each briefly.
shmget(key, size, flags): Creates a new shared memory segment or retrieves an existing one. Returns a shared memory ID (shmid). The key identifies the segment; size specifies bytes; flags include permissions and IPC_CREAT.
shmat(shmid, addr, flags): Attaches the shared memory segment to the calling process's address space. Returns a pointer to the attached memory. The process can then read/write through this pointer.
shmdt(addr): Detaches the shared memory segment from the process. The segment still exists in the kernel but is no longer accessible to this process.
shmctl(shmid, cmd, buf): Performs control operations. Most commonly used with IPC_RMID to mark the segment for destruction (it's actually destroyed when the last process detaches).
Q3: Explain with a diagram how an unnamed pipe works between parent and child processes.
Step 1: Parent calls pipe(fd) â creates fd[0] (read) and fd[1] (write).
Step 2: Parent calls fork() â child inherits both file descriptors.
Step 3: Parent closes fd[0] (read end), keeps fd[1] for writing. Child closes fd[1] (write end), keeps fd[0] for reading.
Data flow: Parent writes to fd[1] â data enters kernel pipe buffer â Child reads from fd[0].
Diagram
Parent Process Kernel Pipe Buffer Child Process
ââââââââââââ ââââââââââââââââ ââââââââââââ
â fd[1]ââââââââââââââââ â â â â â ââââââââââââââââfd[0] â
â (write) â â (FIFO data) â â (read) â
â fd[0] â â ââââââââââââââââ â fd[1] â â
ââââââââââââ (kernel space) ââââââââââââ
Key insight: Closing unused ends is crucial. If the parent doesn't close fd[0], the child's read() will never get EOF because there's still a potential writer (the parent) holding the read end open.
Q4: What are the advantages of named pipes (FIFOs) over unnamed pipes?
1. Unrelated process communication: Any process can open a FIFO by its filesystem path. Unnamed pipes only work between parent-child (fork-inherited file descriptors).
2. Filesystem persistence: FIFOs persist as special files until explicitly deleted (unlink). They survive process restarts â a new process can connect to the same FIFO name.
3. Named identification: FIFOs have a meaningful path (e.g., /tmp/my_app_fifo), making them easy to discover and manage. Unnamed pipes are just integer file descriptors.
4. Server-client pattern: Multiple clients can open and write to the same FIFO, while one server reads from it â enabling many-to-one communication.
Trade-off: FIFOs are still unidirectional and still byte streams (no message boundaries). For bidirectional communication, you need two FIFOs.
Q5: How does IPC manifest in modern microservice architectures? Give an Indian industry example.
In microservices, each service runs as an independent process (or container), making IPC essential. Modern IPC mechanisms include:
Message Queues â Apache Kafka / RabbitMQ: Services produce and consume messages asynchronously. Razorpay uses Kafka for payment event streaming â when a payment succeeds, a Kafka message triggers invoice generation, notification, and analytics updates simultaneously.
Shared Memory â Redis / Memcached: In-memory data stores act as shared memory across services. Swiggy uses Redis to cache restaurant menus â the menu service writes, the search service and order service read from the same Redis instance.
Message Passing â gRPC / REST APIs: Services communicate via structured request-response messages. PhonePe uses gRPC between its payment gateway and bank connector services for low-latency, strongly-typed communication.
Indian Example: When you order food on Swiggy: (1) Order service writes to Kafka queue â (2) Restaurant notification service reads from queue â (3) Delivery assignment service reads from queue â (4) ETA calculation service reads restaurant location from Redis cache â (5) Push notification service sends update via message passing (API call to Firebase). All of these are IPC patterns at scale.
Case Studies
ð Case Study 1: Indian Railways Station Communication System â Modeling IPC
Background
New Delhi Railway Station handles 350+ trains daily, serving 500,000 passengers. The station operates through multiple independent systems that must communicate in real-time: the Central Control Room, Signal Interlocking System, Platform Announcement System, Display Board System, Ticket Reservation System, and Catering Management.
The IPC Model
| Station System | IPC Mechanism | Why This Mechanism? |
|---|---|---|
| Train Position Tracking (GPS data updated every 5 seconds) | Shared Memory | Multiple systems read the same position data simultaneously. Speed is critical â no copying overhead. Semaphores protect concurrent updates. |
| Platform Announcements (Control â PA System) | Named Pipe (FIFO) | One-directional broadcast. Control room writes announcement text; PA system reads and plays it. FIFO ensures order: "Arrival" announcement plays before "Departure." |
| Emergency Alerts (Any dept â All depts) | Priority Message Queue | Emergency alert (priority 9) must be processed before routine messages (priority 1). Message queue ensures the bomb threat alert reaches all departments before the tea stall closure notice. |
| Ticket Booking Updates (IRCTC â Local Counter) | Persistent Message Queue | Booking confirmations must not be lost. If the local counter system is temporarily down, messages wait in the queue. Guaranteed delivery with acknowledgement. |
| Coach-to-Locomotive Signal (Guard â Loco Pilot) | Unnamed Pipe | Direct parent-child style communication. The guard process signals "all clear" to the loco pilot process. Simple, fast, one-shot. |
Questions for Discussion
- If the shared memory segment for train tracking crashes, what happens to the display boards? How would you design a fallback?
- Why is an unnamed pipe suitable for guard-to-loco-pilot communication but not for control-room-to-all-platforms?
- Design a priority scheme for the emergency message queue. What priority levels would you define?
ð Case Study 2: Razorpay Payment Processing â IPC in Microservices
Background
Razorpay processes over 500 million transactions annually for 8 million+ businesses across India. Their architecture consists of 200+ microservices, each running as an independent process (containerized in Kubernetes). These services must communicate reliably, quickly, and at massive scale.
IPC Architecture
When a customer pays â¹999 on an e-commerce site using Razorpay, here's the IPC journey:
| Step | Service | IPC Used | Technical Detail |
|---|---|---|---|
| 1 | API Gateway â Payment Service | gRPC (Message Passing) | Strongly-typed protobuf message with payment amount, merchant ID, payment method. Synchronous call â gateway waits for response. |
| 2 | Payment Service â Kafka | Message Queue (Kafka) | Payment event published to "payments" topic. Asynchronous â payment service continues without waiting for consumers. |
| 3 | Fraud Detection â Redis Cache | Shared Memory (Redis) | Fraud service checks customer's transaction history cached in Redis. Sub-millisecond read. Pattern: "Has this card been used 5+ times in 10 minutes?" |
| 4 | Bank Gateway â NPCI/Bank | REST API (Message Passing) | HTTP request to bank's API with encrypted payment details. Synchronous â must wait for bank's approval/decline response. |
| 5 | Notification Service (from Kafka) | Message Queue (Kafka Consumer) | Consumes "payment_success" event from Kafka. Sends SMS via Twilio API, email via SendGrid API. Asynchronous â runs independently. |
| 6 | Analytics Service (from Kafka) | Message Queue (Kafka Consumer) | Consumes same event for dashboard analytics. Updates real-time merchant dashboard. Non-blocking. |
Key Design Decisions
- Why Kafka instead of POSIX MQ? Scale (millions of messages/sec), persistence (messages stored on disk for replay), consumer groups (multiple consumers independently process the same message stream).
- Why Redis instead of System V shared memory? Network-accessible (works across machines), built-in data structures (hash maps, sorted sets), automatic expiry (TTL).
- Why gRPC instead of REST for inter-service calls? Binary serialization (protobuf) is 10x faster than JSON. Streaming support. Strong typing prevents bugs.
Questions for Discussion
- If Kafka goes down, what happens to payment notifications? How would you design a fallback?
- Why does Razorpay use synchronous IPC (gRPC) for bank communication but asynchronous IPC (Kafka) for notifications?
- Design an IPC architecture for a new "refund processing" service that must guarantee no refund is processed twice.
Chapter Summary
ð Key Takeaways â Unit 9: Inter Process Communication
- IPC is essential because OS processes are isolated by design. They need explicit mechanisms to share data, coordinate actions, and communicate.
- Shared Memory (shmget, shmat, shmdt, shmctl) is the fastest IPC mechanism â zero kernel copy â but requires manual synchronization (semaphores/mutexes) to prevent race conditions.
- Message Passing uses send/receive primitives. It can be direct (name the process) or indirect (via mailbox/port). It can be synchronous (blocking) or asynchronous (non-blocking).
- Unnamed Pipes (pipe()) provide simple, unidirectional, byte-stream communication between parent-child processes. The shell
|operator uses this. - Named Pipes (FIFOs) (mkfifo()) extend pipes to unrelated processes by providing a filesystem name. They persist until explicitly removed.
- popen()/pclose() combine pipe + fork + exec into one convenient function for capturing command output in C programs.
- POSIX Message Queues (mq_open, mq_send, mq_receive) provide prioritized, boundary-preserving message passing. Compile with
-lrt. - Choose the right mechanism: Speed â Shared Memory. Simplicity â Pipes. Priority + Ordering â Message Queues. Unrelated processes â FIFO or MQ.
- Modern IPC: Kafka = distributed message queue. Redis = network shared memory. gRPC = typed message passing. The concepts are the same â the scale is different.
Earning Checkpoint
| Skill Learned | Tool/Method | Portfolio Artifact | Earning Ready? |
|---|---|---|---|
| Unnamed Pipes | C, pipe(), fork() | Parent-child pipe communication program | â Yes â demonstrates systems programming skill |
| Named Pipes (FIFOs) | C, mkfifo() | Two-process FIFO communication program | â Yes â shows IPC between independent processes |
| Shared Memory | C, shmget/shmat | Writer-reader shared memory program | â Yes â key for backend engineering roles |
| Message Queues | C, POSIX MQ | Priority message queue sender/receiver | â Yes â directly applicable to Kafka/RabbitMQ |
| popen/pclose | C | System info capture program | â Yes â useful for DevOps/automation scripts |
| Python Multiprocessing | Python Queue, Process | Multi-process chat system | â Yes â immediately usable for startup prototypes |
| IPC Architecture Design | Conceptual + Case Studies | Railway/Razorpay IPC design analysis | â Yes â system design interview ready |
â Unit 9 complete. MCQs: 30. Ready for Unit 10: Capstone!
[QR: Link to EduArtha video tutorial â Inter Process Communication]