Operating Systems
Unit 2: Process Management
From program to process โ master the lifecycle of processes, system calls that create & control them, and understand how your OS juggles thousands of tasks every second.
โฑ๏ธ Time to Complete: 6 hrs theory + 4 hrs lab | ๐ฐ Earning Potential: โน5,000โโน15,000/month | ๐ 30 MCQs (Bloom's Mapped)
๐ผ Jobs this unlocks: Systems Engineer (โน5โ8 LPA) | Linux Admin (โน4โ7 LPA) | DevOps Intern (โน15Kโ25K/month)
๐ฏ Interview Focus: TCS | Infosys | Amazon | Wipro | GATE CS
Opening Hook โ The Day India's Vaccine Portal Crashed
๐ฅ CoWIN Crashed โ 2 Crore Users, Zero Vaccines Booked
June 21, 2021. India opens COVID-19 vaccination for 18+ age group. At exactly 4:00 PM, 2 crore (20 million) users hit the CoWIN portal simultaneously. The servers didn't just slow down โ they froze completely. Pages returned blank. OTPs never arrived. Slots showed "available" but couldn't be booked.
What happened behind the scenes? Every user request spawned a process on the server. With 20 million near-simultaneous connections, the OS was drowning in processes. Each process needed a Process Control Block (PCB) โ consuming memory. The CPU tried to switch between thousands of processes โ context switching overhead consumed 90%+ of CPU time. The system spent more time switching between processes than actually executing them.
The fix? Engineers implemented process pooling, rate limiting (controlling how many new processes spawn), and queue-based scheduling โ all concepts you'll learn in this chapter.
Could YOU have prevented this crash? After this chapter โ yes, you absolutely could.
Learning Outcomes โ Bloom's Taxonomy Mapped
| Bloom's Level | Learning Outcome |
|---|---|
| ๐ต Remember | Define a process, list all fields of the PCB, and name the 5 process states with valid transitions |
| ๐ต Understand | Explain the difference between program and process, and describe how fork() creates a child process with a copy of the parent's address space |
| ๐ข Apply | Write C programs using fork(), exec(), wait(), and exit() system calls and predict their output, including PID/PPID values |
| ๐ข Analyze | Differentiate between zombie and orphan processes, analyse context switching overhead, and compare co-operating vs independent processes |
| ๐ Evaluate | Evaluate the process management failures in CoWIN/IRCTC crashes and propose solutions using process pooling and rate limiting |
| ๐ Create | Design a process monitoring tool and construct process family trees showing parent-child relationships across multiple fork() calls |
Concept Explanation โ Process Management from Scratch
1. Process Concept โ Program vs Process
Plain English: A program is like a recipe written in a cookbook sitting on a shelf. It does nothing by itself. A process is you actually cooking that recipe โ you've gathered ingredients (memory), you're following steps (program counter), you're using the stove (CPU), and the dish is in progress. The same recipe (program) can be cooked by multiple people (processes) simultaneously.
๐ Program vs Process โ The Key Differences
| Aspect | Program | Process |
|---|---|---|
| Nature | Passive entity (static) | Active entity (dynamic) |
| Existence | Stored on disk (file) | Exists in memory (RAM) |
| Lifecycle | No lifecycle โ just exists | Created โ Runs โ Terminates |
| Resources | None consumed | Uses CPU, memory, I/O, files |
| Multiplicity | One program file on disk | Multiple processes from same program |
| Indian Analogy | A recipe book on the shelf | Actually cooking the dish in the kitchen |
booking.exe file sitting on the server is a program. When 50 lakh users click "Book Ticket" simultaneously, 50 lakh processes are spawned from that same program. Each process has its own passenger details, selected train, and payment status โ even though they all originated from the same program code.
A process in memory consists of 4 segments:
| Segment | What It Stores | Analogy |
|---|---|---|
| Text (Code) | The compiled program instructions | Recipe steps printed on paper |
| Data | Global and static variables | Pre-measured ingredients kept ready |
| Heap | Dynamically allocated memory (malloc) | Extra ingredients fetched as needed during cooking |
| Stack | Function calls, local variables, return addresses | Your mental checklist โ "first chop onions, then fry, then add spices" |
2. Process Control Block (PCB) โ The Aadhaar Card of a Process
Every Indian citizen has an Aadhaar card โ a unique ID with your name, photo, address, and biometrics. Similarly, every process has a Process Control Block (PCB) โ a data structure maintained by the OS that stores everything about that process. When the OS needs to manage a process (pause it, resume it, kill it), it looks at the PCB.
๐๏ธ PCB Fields โ Every Field Explained
| PCB Field | What It Stores | Aadhaar Analogy |
|---|---|---|
| Process ID (PID) | Unique integer identifying the process | Your 12-digit Aadhaar number |
| Process State | Current state: New, Ready, Running, Waiting, Terminated | Your current status โ employed, student, retired |
| Program Counter (PC) | Address of the next instruction to execute | Which page of the recipe book you're on |
| CPU Registers | Values in accumulator, stack pointer, general-purpose registers | What ingredients you're currently holding in your hands |
| Memory Limits | Base/limit registers, page table info | Your registered address โ where you live |
| Open Files List | File descriptors for all open files | Documents you're currently working with |
| Scheduling Info | Priority, scheduling queue pointers, CPU time used | Your place in the queue at a government office |
| I/O Status | List of I/O devices allocated, pending I/O requests | Which counter/window is serving you |
| Accounting Info | CPU time consumed, time limits, job/process numbers | Your bank passbook โ how much "CPU currency" you've spent |
| Parent PID (PPID) | PID of the process that created this process | Your father's Aadhaar number on your birth certificate |
C Struct // Simplified PCB structure (conceptual, not actual Linux kernel code) struct PCB { int pid; // Process ID (unique) int ppid; // Parent Process ID enum state; // NEW, READY, RUNNING, WAITING, TERMINATED int program_counter; // Address of next instruction int registers[16]; // CPU register snapshot int priority; // Scheduling priority void* memory_base; // Start of memory allocation int memory_limit; // Memory boundary int open_files[256]; // File descriptor table long cpu_time_used; // Total CPU time consumed };
3. Process States & State Transition Diagram
A process goes through 5 states during its lifetime โ just like a passenger on an Indian Railway journey:
| State | Meaning | Railway Analogy |
|---|---|---|
| New | Process is being created | You've just booked a ticket โ you're in the system but haven't reached the station yet |
| Ready | Process is loaded in RAM, waiting for CPU | You're at the platform, bag packed, waiting for the train to arrive |
| Running | Process is currently executing on CPU | You're on the train โ it's moving, you're traveling! |
| Waiting (Blocked) | Process is waiting for I/O or an event | Train stopped at a signal โ waiting for the track to clear |
| Terminated | Process has finished execution | You've reached your destination and exited the station |
State Transition Diagram (ASCII Art)
Every Transition Explained
| Transition | When It Happens | Indian Example |
|---|---|---|
| New โ Ready | OS admits the process, loads it into memory | IRCTC accepts your booking request, puts you in the queue |
| Ready โ Running | CPU scheduler picks this process (dispatch) | Your token number is called at the bank counter |
| Running โ Ready | Timer interrupt / time quantum expires (preemption) | Bank clerk says "next please" โ you go back to waiting with your half-done form |
| Running โ Waiting | Process needs I/O (disk read, network, user input) | Clerk says "bring your PAN card photocopy from the Xerox shop" โ you leave the counter |
| Waiting โ Ready | I/O operation completes | You return with the photocopy and rejoin the queue |
| Running โ Terminated | Process calls exit() or finishes execution | Your work at the bank is done, you leave |
4. Operations on Processes โ fork(), exec(), wait(), exit()
4.1 fork() โ Creating a Child Process
fork() creates a new child process that is an almost exact copy of the parent. It's like a cell dividing โ one becomes two. Both parent and child continue executing from the line after fork().
๐ How fork() Works โ Step by Step
- Parent process calls
fork() - OS creates a new PCB for the child process
- Child gets a copy of parent's text, data, heap, and stack segments
- Child gets a new unique PID, but its PPID = parent's PID
fork()returns twice:- Returns child's PID (a positive number) to the parent
- Returns 0 to the child
- Returns -1 if fork fails (e.g., memory full)
- Both parent and child continue executing the next line after fork()
C #include <stdio.h> #include <unistd.h> #include <sys/types.h> int main() { pid_t pid; printf("Before fork: I am process %d\n", getpid()); pid = fork(); // This is where the magic happens! if (pid < 0) { fprintf(stderr, "Fork failed!\n"); return 1; } else if (pid == 0) { // CHILD process โ fork() returned 0 printf("CHILD: My PID = %d, My Parent's PID = %d\n", getpid(), getppid()); } else { // PARENT process โ fork() returned child's PID printf("PARENT: My PID = %d, Child's PID = %d\n", getpid(), pid); } printf("This line executes in BOTH parent and child! (PID: %d)\n", getpid()); return 0; }
4.2 exec() Family โ Replacing the Process Image
exec() replaces the current process's code with a completely different program. The PID remains the same, but the process is now running different code. It's like a person changing their career โ same person (PID), new job (program).
C #include <stdio.h> #include <unistd.h> int main() { printf("Before exec: PID = %d\n", getpid()); // Replace this process with the "ls -l" command execlp("ls", "ls", "-l", NULL); // This line NEVER executes if exec succeeds! printf("This won't print โ exec replaced us!\n"); return 0; }
execl, execlp, execle, execv, execvp, execve. The naming pattern: l = list of args, v = vector (array) of args, p = search PATH, e = pass environment. For exams, knowing execlp and execvp is enough.
4.3 wait() โ Parent Waits for Child
wait() makes the parent process pause and wait until one of its child processes terminates. This prevents zombie processes and allows the parent to collect the child's exit status.
C #include <stdio.h> #include <unistd.h> #include <sys/wait.h> int main() { pid_t pid = fork(); if (pid == 0) { // Child printf("Child (PID %d): Doing some work...\n", getpid()); sleep(3); // Simulate 3 seconds of work printf("Child: Done! Exiting.\n"); return 42; // Exit with status 42 } else { // Parent int status; printf("Parent (PID %d): Waiting for child...\n", getpid()); wait(&status); // Block until child finishes printf("Parent: Child exited with status %d\n", WEXITSTATUS(status)); } return 0; }
4.4 exit() โ Terminating a Process
exit(status) terminates the calling process. The integer status is passed to the parent via wait(). Convention: exit(0) = success, non-zero = error.
return from main() with exit(). In main(), return 0; and exit(0); are functionally the same. But inside any other function, return only exits that function, while exit() terminates the entire process immediately.
5. Zombie & Orphan Processes
5.1 Zombie Process โ "Dead But Not Buried"
A zombie process is a child that has terminated (called exit()), but its parent hasn't called wait() to collect its exit status. The child's PCB still exists in the process table โ taking up space but doing nothing. It's like a person who has died but whose death certificate hasn't been collected โ they're still in government records.
C โ Creating a Zombie #include <stdio.h> #include <unistd.h> #include <stdlib.h> int main() { pid_t pid = fork(); if (pid == 0) { // Child: exit immediately printf("Child (PID %d): I'm done. Becoming zombie...\n", getpid()); exit(0); } else { // Parent: sleep without calling wait() โ child becomes zombie! printf("Parent (PID %d): Sleeping 30s. NOT calling wait().\n", getpid()); printf("Run 'ps aux | grep Z' in another terminal to see the zombie!\n"); sleep(30); // During this 30s, child is a zombie } return 0; }
5.2 Orphan Process โ "Parent Left Without Me"
An orphan process is a child whose parent has terminated before the child. In Linux, orphans are "adopted" by the init process (PID 1) or systemd, which becomes their new parent and will call wait() for them.
C โ Creating an Orphan #include <stdio.h> #include <unistd.h> #include <stdlib.h> int main() { pid_t pid = fork(); if (pid == 0) { // Child: keep running after parent exits sleep(5); printf("Child (PID %d): My parent left! New parent PID = %d\n", getpid(), getppid()); // getppid() will now return 1 (init) or systemd's PID } else { // Parent: exit immediately, abandoning the child printf("Parent (PID %d): I'm leaving! Child PID = %d\n", getpid(), pid); exit(0); } return 0; }
| Property | Zombie Process | Orphan Process |
|---|---|---|
| What | Child exited, parent didn't call wait() | Parent exited before child |
| State | Terminated (Z state) | Still running (adopted by init) |
| Dangerous? | Yes โ fills up process table | No โ init handles cleanup properly |
| Fix | Parent must call wait() or use signal handlers | No fix needed โ OS handles it |
| Analogy | Unclaimed package at post office | Child at orphanage โ adopted by the state |
6. Co-operating vs Independent Processes
| Property | Independent Process | Co-operating Process |
|---|---|---|
| Data Sharing | Cannot affect or be affected by other processes | Shares data with other processes |
| Execution | Deterministic โ same input โ same output every time | Non-deterministic โ output depends on execution order |
| Synchronisation | Not needed | Required (semaphores, mutexes, etc.) |
| Example | Two students taking different exams in different rooms | Two chefs cooking the same dish โ one chops, other fries |
Why do we need co-operating processes?
- Information Sharing: Multiple users accessing a shared database (like IRCTC seat availability)
- Computation Speedup: Break a large task into subtasks running in parallel (like MapReduce)
- Modularity: Build systems from separate interacting modules (microservices at Flipkart)
- Convenience: A user can edit a document, print, and compile code simultaneously
7. Context Switching โ The Hidden Cost of Multitasking
Plain English: Imagine you're studying Maths. Your phone rings โ it's your friend. You bookmark your Maths page, put the book down, talk for 5 minutes, then pick up Maths again from the bookmarked page. That entire process of saving your Maths state โ switching to phone โ restoring Maths state is a context switch. The 5 minutes on the phone was productive, but the 30 seconds of bookmarking + finding your page again was overhead โ wasted time.
๐ Context Switch โ Step by Step
When the OS switches from Process A to Process B:
- Save state of Process A: Copy all CPU register values, program counter, and stack pointer into A's PCB
- Update A's PCB: Change A's state from Running to Ready (or Waiting)
- Move A's PCB: Place A's PCB into the appropriate queue (ready queue or wait queue)
- Select Process B: The scheduler picks B from the ready queue
- Load state of Process B: Copy B's saved register values, PC, and SP from B's PCB into the CPU
- Update B's PCB: Change B's state from Ready to Running
- Resume B: CPU starts executing B from where it last left off
Context Switching Overhead Analysis
| Factor | Impact | Typical Time |
|---|---|---|
| Register save/restore | Must save/load all CPU registers | ~1-2 microseconds |
| Memory mapping | TLB flush, page table switch | ~5-10 microseconds |
| Cache invalidation | CPU cache becomes useless for new process (cold cache) | Indirect โ causes cache misses for ~100ฮผs |
| Pipeline flush | CPU instruction pipeline must be flushed | ~10-20 cycles |
| Total overhead | Per context switch | ~5-20 microseconds on modern hardware |
Learn by Doing โ 3-Tier Lab Structure
๐ข Tier 1 โ GUIDED TASK: fork() Family Tree in C
Objective:
Write a C program where a parent creates 2 children. Each child prints its PID and PPID, forming a family tree.
Step 1: Create the Source File
Open terminal (WSL on Windows, or native Linux/Mac terminal). Create a file:
Bash nano family_tree.c
Step 2: Write the Code
C #include <stdio.h> #include <unistd.h> #include <sys/wait.h> int main() { pid_t pid1, pid2; printf("========================================\n"); printf(" PROCESS FAMILY TREE DEMO\n"); printf("========================================\n"); printf("PARENT: PID = %d\n\n", getpid()); // Create first child pid1 = fork(); if (pid1 == 0) { // First child printf(" CHILD 1: PID = %d, Parent PID = %d\n", getpid(), getppid()); printf(" CHILD 1: I am the elder sibling!\n\n"); sleep(2); return 0; // IMPORTANT: Child must exit here! } // Create second child (only parent reaches here) pid2 = fork(); if (pid2 == 0) { // Second child printf(" CHILD 2: PID = %d, Parent PID = %d\n", getpid(), getppid()); printf(" CHILD 2: I am the younger sibling!\n\n"); sleep(2); return 0; // IMPORTANT: Child must exit here! } // Only parent reaches here int status; waitpid(pid1, &status, 0); printf("PARENT: Child 1 (PID %d) exited.\n", pid1); waitpid(pid2, &status, 0); printf("PARENT: Child 2 (PID %d) exited.\n", pid2); printf("\n========================================\n"); printf(" FAMILY TREE:\n"); printf(" Parent (PID %d)\n", getpid()); printf(" / \\\n"); printf(" Child1 (%d) Child2 (%d)\n", pid1, pid2); printf("========================================\n"); return 0; }
Step 3: Compile
Bash gcc -o family_tree family_tree.c
Step 4: Run
Bash
./family_tree
Expected Output:
return 0; in child blocks is the #1 bug. Without it, both children will continue executing the parent's code and create their own children โ resulting in 4 processes instead of 3. Always terminate child blocks explicitly.
Step 5: Verify with System Tools
While the program runs (increase sleep to 30 seconds), open another terminal:
Bash # See the process tree pstree -p | grep family_tree # Alternative: ps command ps -ef | grep family_tree
๐ Congratulations! You've created your first process family tree. Take a screenshot โ this is your portfolio piece!
๐ก Tier 2 โ SEMI-GUIDED TASK: Zombie & Orphan Process Demos
Task A: Create a Zombie Process
Write a C program that creates a zombie. Verify it using ps.
Hints:
- Fork a child process
- Make the child call
exit(0)immediately - Make the parent NOT call wait() โ instead,
sleep(30) - In another terminal, run:
ps aux | grep Zโ you should see the zombie with state "Z+" - After parent's sleep ends, the zombie disappears (parent exits, init cleans up)
Task B: Create an Orphan Process
Write a C program where the parent exits first, leaving the child orphaned.
Hints:
- Fork a child process
- Make the parent call
exit(0)immediately - Make the child
sleep(10), then print its new PPID - The child's new PPID should be 1 (init) or the PID of systemd
- Key observation: the child continues running even after the parent dies
๐ด Tier 3 โ OPEN CHALLENGE: Real-Time Process Monitor
The Brief:
Build a real-time process monitor in Python or Bash that tracks process creation and termination on your system.
Requirements:
- List all running processes with PID, PPID, state, CPU%, and memory%
- Detect new processes โ poll every 2 seconds and show newly created processes
- Detect terminated processes โ show processes that disappeared since last check
- Filter zombies โ highlight any zombie processes in red (use ANSI colour codes)
- Show process tree โ display parent-child relationships for a given PID
Tools You Might Use:
- Python:
psutillibrary,osmodule,subprocess - Bash:
ps,pstree,top,watch,diff
Industry Spotlight โ A Day in the Life
๐จโ๐ป Vikram Iyer, 27 โ Systems Engineer at Amazon India, Hyderabad
Background: B.Tech (CSE) from NIT Warangal. Fascinated by how Linux manages millions of processes on Amazon's servers. Got placed through campus recruitment after excelling in OS and Computer Networks.
A Typical Day:
9:00 AM โ Morning standup with the EC2 infrastructure team. Review overnight alerts โ any processes that crashed or leaked memory on production servers.
10:00 AM โ Use strace to trace system calls on a misbehaving process. Found that a process was doing 10,000 unnecessary fork() calls per minute โ causing context switching overhead on the host machine.
11:30 AM โ Use gdb (GNU Debugger) to attach to a running process and inspect its state. Found a race condition between two co-operating processes sharing a database connection.
1:00 PM โ Lunch at Amazon's cafeteria. Discuss kernel tuning parameters with a senior engineer โ they're adjusting the scheduler's time quantum for better process throughput.
2:00 PM โ Write a systemd service file for a new microservice. Configure process restart policies, resource limits (max memory, max CPU), and logging.
4:00 PM โ Use perf to profile context switching overhead on a busy server. Found that reducing the number of worker processes from 500 to 50 (using process pooling) cut overhead by 80%.
5:30 PM โ Learning session: studying Linux kernel source code for process scheduling (CFS โ Completely Fair Scheduler).
| Detail | Info |
|---|---|
| Tools Used Daily | Linux CLI, strace, gdb, perf, systemd, htop, ps, /proc filesystem, Python scripts |
| Entry Salary (2024) | โน5โ8 LPA + benefits |
| Mid-Level (3โ5 yrs) | โน12โ22 LPA |
| Senior (7+ yrs) | โน25โ50 LPA |
| Companies Hiring | Amazon, Google, Microsoft, Flipkart, Oracle, Red Hat, VMware, Samsung R&D, Qualcomm, TCS, Infosys (ISU), HCLTech |
Earn With It โ Freelance & Income Roadmap
๐ฐ Your Earning Path After This Chapter
Portfolio Piece: "Linux Process Monitor Script" โ a Python/Bash tool that monitors processes, detects zombies, and shows process trees. Put it on GitHub with a professional README.
Beginner Gig Ideas:
โข Process monitoring scripts for small servers โ โน3,000โโน10,000
โข systemd service file creation for startups โ โน2,000โโน5,000
โข Linux server health-check automation scripts โ โน5,000โโน15,000
โข DevOps interview prep tutoring (process management concepts) โ โน500โโน1,000/hour
| Platform | Best For | Typical Rate |
|---|---|---|
| Internshala | Linux admin internships | โน10,000โโน25,000/month |
| Fiverr | Shell script gigs, server monitoring | $15โ$80/gig (โน1,200โโน6,500) |
| Upwork | DevOps / Linux sysadmin projects | $20โ$50/hour |
| Freelance DevOps consulting | โน5,000โโน15,000/project | |
| Toptal | Senior DevOps roles (after experience) | $50โ$100/hour |
โฑ๏ธ Time to First Earning: 3โ4 weeks (complete Tier 1 & 2 labs, build GitHub portfolio, apply on Internshala for Linux/DevOps internships)
ls in the terminal?" Answer: The shell calls fork() to create a child process, then the child calls exec("ls") to replace itself with the ls program, parent calls wait() to wait for ls to finish. Knowing this wins you the job.
MCQ Assessment Bank โ 30 Questions (Bloom's Mapped)
Remember / Identify (Q1โQ5)
A process is different from a program because:
- A process is stored on disk
- A process is an active entity in memory with its own PCB, while a program is a passive file on disk
- A program can use CPU directly
- There is no difference
Which of the following is NOT a field in the Process Control Block (PCB)?
- Process ID (PID)
- Program Counter
- Hard Disk RPM
- CPU Register values
The correct sequence of process states is:
- New โ Running โ Ready โ Terminated
- New โ Ready โ Running โ Waiting/Terminated
- Ready โ New โ Running โ Waiting
- Running โ New โ Ready โ Terminated
The fork() system call returns:
- Always returns 0
- Returns child's PID to parent and 0 to child
- Returns parent's PID to both
- Returns nothing
A zombie process is created when:
- A process uses too much memory
- A child process terminates but the parent hasn't called wait()
- The CPU overheats
- Two processes deadlock
Understand / Explain (Q6โQ10)
Why is there no direct transition from Waiting state to Running state?
- Because the CPU is always free
- Because after I/O completes, the process must re-enter the Ready queue and wait for the scheduler to assign CPU
- Because waiting processes are always terminated
- Because the OS doesn't track waiting processes
Explain what happens to the address space when fork() is called:
- The child shares the same memory as the parent
- The child gets a copy of the parent's text, data, heap, and stack segments in its own memory space
- The parent's memory is deleted
- No memory is allocated to the child
How does exec() differ from fork()?
- exec() creates a new process; fork() replaces the image
- fork() creates a new child process; exec() replaces the current process's code with a new program without creating a new process
- Both do the same thing
- exec() only works on Windows
Why does the OS need to save CPU register values during a context switch?
- To increase CPU speed
- So that when the process resumes later, it can continue exactly from where it stopped โ registers hold the process's computation state
- To delete the process
- Registers are never saved
What happens to an orphan process in Linux?
- It is immediately killed
- It becomes a zombie
- It is adopted by the init process (PID 1), which becomes its new parent
- It continues with no parent forever
Apply / Demonstrate (Q11โQ15)
What is the total number of processes created by the following code? fork(); fork(); fork();
- 3
- 6
- 7
- 8
In the following code, how many times is "Hello" printed?fork(); printf("Hello\n"); fork(); printf("Hello\n");
- 2
- 4
- 6
- 8
To run the ls -la command from within a C program using exec, the correct call is:
execlp("ls", "ls", "-la", NULL);exec("ls -la");fork("ls -la");run("ls", "-la");
execlp searches PATH for "ls", passes arguments as a list (l), and requires NULL termination. The first "ls" is the path, the second "ls" is argv[0] by convention.A parent creates a child using fork(). The parent then calls wait(&status). If the child exits with exit(5), what value does WEXITSTATUS(status) return?
- 0
- 5
- -1
- Undefined
WEXITSTATUS(status) extracts the exit code passed to exit() by the child. The child called exit(5), so the macro returns 5.You need to write a shell that executes user commands. The correct approach using system calls is:
- Directly call exec() in the shell's main process
- fork() a child, call exec() in the child to run the command, parent calls wait() for the child to finish
- Use only wait() without fork()
- Call exit() after every command
Analyze / Compare (Q16โQ20)
Compare zombie and orphan processes. Which is more harmful to system stability?
- Orphan โ because it runs without a parent
- Zombie โ because it occupies process table entries without releasing them, potentially filling the process table
- Both are equally harmful
- Neither is harmful
Analyse why context switching overhead increases when the number of processes increases significantly:
- Because each process needs more RAM
- Because the CPU spends more time saving/restoring process states and less time doing actual work, and cache/TLB misses increase
- Because the disk becomes full
- Because context switching doesn't cause overhead
Differentiate between the text segment and the stack segment of a process:
- Both store the same data
- Text stores executable code (read-only, shared); Stack stores function calls, local variables, and return addresses (read-write, per-process)
- Stack stores the program binary
- Text is on disk; Stack is on the network
Analyse why fork() followed by exec() is used instead of a single "create process with new program" call:
- Because exec() is faster alone
- Separating creation (fork) from program loading (exec) gives flexibility โ the child can set up file descriptors, environment variables, and pipes between fork and exec
- There is no reason; it's just historical
- Because exec() creates a new process
ls | grep .c.Compare independent and co-operating processes in the context of IRCTC's ticket booking system:
- All IRCTC processes are independent
- The booking process, payment gateway process, and seat allocation process are co-operating processes that share the seat database and must synchronise to prevent double-booking
- Co-operating processes don't need synchronisation
- IRCTC uses only one process
Evaluate / Judge (Q21โQ25)
CoWIN crashed when 2 crore users hit simultaneously. Evaluate which process management concept was the primary failure point:
- The programming language was wrong
- Excessive process creation without pooling caused context switching overhead to consume nearly all CPU time, leaving no capacity for actual request processing
- The servers had too much RAM
- The database was too fast
A developer's server has 10,000 zombie processes. They say "zombies use no CPU, so they're harmless." Evaluate this claim:
- Correct โ zombies are completely harmless
- Incorrect โ while zombies don't use CPU, they occupy entries in the process table (finite size). When the table fills up, no new processes can be created, causing fork() to fail for ALL programs
- Correct โ zombies are automatically cleaned
- Incorrect โ zombies use 100% CPU
Evaluate: "Using exec() without fork() first is always a mistake." Is this true?
- True โ exec must always follow fork
- False โ exec() without fork() is valid when you intentionally want to replace the current process (e.g., a login shell calling exec to replace itself with the user's shell)
- False โ exec() can create new processes
- True โ exec() crashes without fork()
IRCTC uses a single-process model for handling Tatkal bookings. Evaluate this design decision:
- Excellent โ one process is simplest
- Terrible โ a single process can only handle one booking at a time. With 25 million requests, the queue would be hours long. Multi-process or multi-threaded architecture is essential
- Good if the server is fast enough
- It doesn't matter how many processes are used
A team argues: "We should increase the time quantum from 10ms to 1000ms to reduce context switching." Evaluate the trade-off:
- Great idea with no downsides
- Reduces context switching overhead but increases response time for interactive processes โ a 1s quantum means a user might wait up to 1s for their keypress to be processed, making the system feel unresponsive
- Terrible idea โ bigger quantum always causes crashes
- Time quantum has no effect on performance
Create / Design (Q26โQ30)
Design a solution to prevent zombie processes in a long-running server application:
- Never use fork()
- Use signal(SIGCHLD, SIG_IGN) to automatically clean up child processes, or install a SIGCHLD handler that calls waitpid(-1, NULL, WNOHANG) in a loop
- Restart the server every hour
- Kill all child processes immediately after creation
Design a process architecture for a CoWIN-like vaccination booking system that can handle 2 crore concurrent users without crashing:
- One process per user request
- Process pooling (pre-fork a fixed number of worker processes), queue-based request handling, load balancing across multiple servers, and rate limiting at the gateway
- Use a single thread for all users
- Turn off the server during peak hours
Create a process family tree for the following code. How many leaf processes exist?
pid = fork();
if (pid == 0) {
fork();
}
fork();
- 2 leaf processes
- 3 leaf processes
- 4 leaf processes
- 5 leaf processes
Design a shell command pipeline cat file.txt | grep "error" | wc -l using fork/exec/wait. How many processes are created?
- 1 process
- 3 child processes (one for cat, one for grep, one for wc), connected by 2 pipes
- 6 processes
- No processes are needed
Design a process monitoring alert system for Amazon's EC2 servers. Which metrics should trigger automatic alerts?
- Only CPU temperature
- Zombie process count > threshold, process table usage > 80%, context switch rate > 50,000/sec, any process consuming > 90% CPU for > 5 minutes, fork() failure rate increasing
- Number of keyboard presses
- Only RAM usage
Short Answer Questions (2โ3 marks each)
Question 1 (2 marks)
Differentiate between a program and a process. Give one real-world analogy.
Question 2 (3 marks)
Draw the process state transition diagram showing all 5 states and label each transition with the event that triggers it.
Question 3 (3 marks)
Explain what happens step-by-step when fork() is called. What values does it return to the parent and child? Write a 5-line C code snippet demonstrating fork() with PID printing.
Question 4 (2 marks)
Differentiate between zombie and orphan processes. Which one is more dangerous and why?
Question 5 (3 marks)
Explain context switching with a diagram. List 3 sources of overhead during a context switch and explain why context switching is called "pure overhead."
Long Answer & Case Studies (10 marks each)
๐ Case Study 1: CoWIN Vaccine Portal Crash โ A Process Management Post-Mortem (10 marks)
On June 21, 2021, India opened COVID-19 vaccination registration for all adults (18+). The CoWIN portal, managed by the National Informatics Centre (NIC), received approximately 2 crore (20 million) concurrent requests at 4:00 PM. The portal became completely unresponsive. Users saw blank pages, OTPs failed, and vaccination slots couldn't be booked for several hours.
Post-incident analysis revealed: the server's process table filled up within 30 seconds of launch. Each HTTP request created a new process. Context switching overhead consumed 92% of CPU time. The remaining 8% was insufficient to process even basic page loads.
Answer the following:
- (2 marks) Explain the role of the Process Control Block in this scenario. Why did the process table fill up? What happens when the process table is full?
- (3 marks) Calculate: If each process creation takes 0.5ms and context switch takes 15ฮผs, and the server had a 4-core CPU with a process table limit of 32,768 โ how quickly would the table fill? How many context switches per second would occur with 32,768 active processes?
- (2 marks) Propose a process pooling solution. How does pre-forking a fixed pool of worker processes prevent this crash?
- (3 marks) Design a complete architecture (with diagram) for a "crash-proof" CoWIN system using concepts from this chapter: process pooling, rate limiting, queue-based request handling, and graceful process termination.
๐ Case Study 2: Aadhaar Biometric Authentication โ Process Management at 100 Million Requests/Day (10 marks)
India's Aadhaar system, managed by UIDAI, processes over 100 million biometric authentication requests daily. When a citizen places their fingerprint on a scanner at a bank for eKYC, the system must: capture the biometric, create a process to handle the authentication request, match against 1.4 billion stored fingerprints, and return a yes/no result โ all within 200 milliseconds.
The system runs on distributed Linux servers. Each authentication spawns a child process that performs the biometric matching. The parent process manages the connection pool and request queue.
Answer the following:
- (2 marks) Identify which process operations (fork, exec, wait, exit) are used in the authentication flow. Draw the process lifecycle for a single authentication request.
- (3 marks) With 100 million requests/day, calculate the average requests per second. If each request process lives for 200ms, how many concurrent processes exist at any moment? What are the implications for the process table and context switching?
- (2 marks) Explain how zombie processes could accumulate in this system if the parent process has a bug in its wait() handling. What would be the consequences?
- (3 marks) Design a process management strategy for Aadhaar's authentication servers that minimises context switching, prevents zombie accumulation, and ensures 99.99% uptime. Include specific system calls and Linux commands you would use.
Chapter Summary โ Tweet-Sized Bullet Points
๐ Key Takeaways
- ๐ฆ Program vs Process: Program = static file on disk (recipe). Process = active entity in memory with its own PCB, registers, and state (cooking the dish).
- ๐๏ธ PCB = Aadhaar of a process: Contains PID, state, program counter, registers, memory limits, open files, scheduling info, accounting info.
- ๐ 5 process states: New โ Ready โ Running โ Waiting โ Terminated. No direct WaitingโRunning transition!
- ๐ด fork(): Creates child process (copy of parent). Returns child's PID to parent, 0 to child, -1 on failure.
- ๐ exec(): Replaces current process's code with a new program. Same PID, different code. Code after exec() never executes.
- โณ wait(): Parent blocks until child terminates. Prevents zombies. Collects child's exit status.
- ๐ Zombie: Child exited, parent didn't wait(). Occupies process table entry. Dangerous in large numbers.
- ๐ถ Orphan: Parent exited before child. Safely adopted by init (PID 1). Not dangerous.
- ๐ค Co-operating processes share data and need synchronisation (like IRCTC's booking + allocation systems).
- โก Context switching saves/restores process state via PCB. ~5-20ฮผs overhead per switch. Too many processes โ thrashing.
- ๐ฅ CoWIN crashed because uncontrolled process creation โ process table full โ context switching overhead โ CPU thrashing.
- ๐ฐ Earn NOW: Linux process monitoring scripts on GitHub โ freelance DevOps gigs โน3Kโโน10K on Internshala/Fiverr.
My Earning Checkpoint โ Self-Assessment
| Skill Learned | Tool Practised | Portfolio Item Added | Gig Ready? |
|---|---|---|---|
| Process Concept & PCB | Conceptual / Diagrams | Process state diagram | โ Yes โ can explain in interviews |
| fork() / exec() / wait() | GCC on Linux/WSL | Family Tree C program | โ Yes โ core Linux interview skill |
| Zombie & Orphan Processes | C + ps/pstree commands | Zombie & Orphan demo programs | โ Yes โ debugging skill for DevOps |
| Context Switching | Conceptual + Calculation | Overhead analysis notes | โ Yes โ system tuning knowledge |
| Process Monitoring | Python / Bash scripting | Linux Process Monitor Script | โ Yes โ โน3Kโโน10K/project on Fiverr |
| System Design (CoWIN) | Architecture diagrams | Crash analysis case study | โ Yes โ shows system thinking in interviews |
โ Unit 2 complete. MCQs: 30. Ready for Unit 3: CPU Scheduling!
[QR: Link to EduArtha video tutorial โ Process Management]