Operating Systems: Complete Notes
By Rishtaara Editorial Team36 min read
#OS#Processes#Memory#Scheduling
Processes, threads, scheduling, memory management, deadlocks, and file systems.
Role of an operating system
An OS is a resource manager between hardware and applications. It handles CPU scheduling, memory management, file storage, networking, and security.
- Abstraction: files, processes, sockets.
- Isolation: one app crash should not kill the system.
- Efficiency: maximize throughput and responsiveness.
Kernel and user mode
System call boundary
#include <unistd.h>
#include <stdio.h>
int main(void) {
pid_t pid = getpid(); // user-space app calling kernel API
printf("Current PID: %d
", pid);
return 0;
}Conceptual differences
- Process: independent address space and resources.
- Thread: execution unit within a process, shares memory.
- Context switching between threads is typically cheaper than between processes.
Threading example
Two Python threads doing work
import threading
import time
def worker(name):
for i in range(3):
print(f"{name} -> step {i}")
time.sleep(0.2)
t1 = threading.Thread(target=worker, args=("A",))
t2 = threading.Thread(target=worker, args=("B",))
t1.start()
t2.start()
t1.join()
t2.join()Scheduling goals
- Minimize waiting time and turnaround time.
- Maximize CPU utilization and throughput.
- Prevent starvation and keep fairness.
Common algorithms
- FCFS: simple, can cause convoy effect.
- SJF/SRTF: efficient average wait, needs burst prediction.
- Round Robin: good responsiveness with time quantum.
- Priority scheduling: can starve low-priority tasks without aging.
Round Robin simulation sketch
type Job = { id: string; burst: number };
function roundRobin(queue: Job[], quantum: number): string[] {
const timeline: string[] = [];
const jobs = queue.map((j) => ({ ...j }));
while (jobs.length) {
const job = jobs.shift()!;
const run = Math.min(job.burst, quantum);
timeline.push(`${job.id} ran for ${run}`);
job.burst -= run;
if (job.burst > 0) jobs.push(job);
}
return timeline;
}Key memory concepts
- Virtual memory gives each process a private address space.
- Paging maps virtual pages to physical frames.
- TLB caches recent page-table lookups.
- Page faults occur when required pages are not in RAM.
Address translation flow
CPU generates virtual address -> MMU checks TLB -> page table lookup (if miss) -> physical frame resolved -> data fetched.
High page-fault rates cause thrashing and major performance drops.
Deadlock conditions
If all four conditions hold simultaneously, deadlock can happen. Breaking any one condition helps prevention.
- Mutual exclusion
- Hold and wait
- No preemption
- Circular wait
Simple lock ordering strategy
Acquire locks in fixed order
Object lockA = new Object();
Object lockB = new Object();
// Always acquire A then B in every thread.
synchronized (lockA) {
synchronized (lockB) {
// critical section
}
}How file systems organize data
- Metadata: filename, size, permissions, timestamps.
- Inodes (or equivalent) map file metadata to data blocks.
- Directories map human-readable names to file records.
- Journaling improves crash recovery consistency.
Directory and inode inspection
Inspect file metadata on Unix
ls -li notes.txt
# First column is inode number
stat notes.txt
# Shows size, blocks, permissions, and timestampsVMs vs containers
- VM: virtualized hardware with separate guest OS kernels.
- Container: process-level isolation sharing host kernel.
- Containers start faster and are lighter; VMs provide stronger isolation boundaries.
Containerized process example
Run isolated Nginx container
docker run --name demo-nginx -p 8080:80 nginx:stable
# Starts Nginx in an isolated container namespace
docker ps
docker stop demo-nginxProject scope
Create a small web or CLI app that simulates process scheduling and memory paging events. Allow users to input jobs and visualize turnaround metrics.
- Round Robin or SJF scheduler module.
- Page replacement demo (FIFO or LRU).
- Metrics dashboard: wait time, completion time, page faults.
Sample process model
Representing workload
type Process = {
pid: string;
arrival: number;
burst: number;
priority: number;
};
const workload: Process[] = [
{ pid: "P1", arrival: 0, burst: 6, priority: 2 },
{ pid: "P2", arrival: 1, burst: 4, priority: 1 },
{ pid: "P3", arrival: 2, burst: 8, priority: 3 },
];Key Takeaways
- Operating systems balance abstraction, isolation, and performance.
- Processes, threads, and scheduling directly affect responsiveness.
- Virtual memory and paging make modern multitasking practical.
- Deadlocks are prevented by design discipline, not luck.
- A simulator project strengthens intuition beyond theory.