Learn/cs fundamentals/Operating Systems
Intermediate~20 min read

Operating Systems

Processes, threads, CPU scheduling, memory management, deadlocks, and file systems.

ProcessesThreadsMemoryScheduling

What Does an OS Do?

An operating system is the software layer between hardware and applications. It manages the CPU, memory, storage, and I/O devices — abstracting the hardware so programs don't have to deal with it directly. Core responsibilities: process management, memory management, file systems, and I/O.

Processes and Threads

A process is an independent program in execution — it has its own memory space (code, heap, stack), file handles, and CPU state. Threads are lightweight execution units within a process that share the same memory space but have their own stack and registers.

AspectProcessThread
MemorySeparate address spaceShared with other threads in same process
Creation costHigh (fork copies address space)Low (shares most resources)
CommunicationIPC: pipes, sockets, shared memoryDirect shared memory (needs synchronisation)
IsolationCrash doesn't affect other processesOne thread crash can kill the whole process
Use caseIsolated services (microservices, web workers)Parallel tasks within an app (server requests)

Process States

A process moves through states during its life. The OS scheduler decides which ready process runs next.

New  →  Ready  →  Running  →  Terminated
                  ↑    ↓            ↑
                  Wait ←  I/O event / sleep
                  (Waiting/Blocked)
  • New — being created
  • Ready — in the run queue, waiting for CPU
  • Running — executing on CPU right now
  • Waiting/Blocked — waiting for I/O or an event (not using CPU)
  • Terminated — finished or killed

CPU Scheduling

The scheduler decides which ready process gets the CPU next. The goal is to maximise CPU utilisation and throughput while minimising turnaround time and response time.

AlgorithmHow it worksProblem
FCFSFirst Come First Served — run in arrival order, non-preemptiveConvoy effect — one slow process blocks everything
SJFShortest Job First — run shortest burst time nextCan't know burst time in advance; starvation of long jobs
Round RobinEach process gets a fixed time quantum; preemptiveHigh context-switch overhead if quantum too small
PriorityHigher-priority process runs firstStarvation — low-priority processes may never run (fix: aging)
MLFQMulti-Level Feedback Queue — adjusts priority based on behaviourComplex to tune; most real OS schedulers are based on this

Memory Management

Each process thinks it has exclusive access to a large, contiguous address space — this is virtual memory. The OS translates virtual addresses to physical RAM addresses using a page table.

Paging

Memory is divided into fixed-size pages (virtual) and frames (physical), typically 4KB. The page table maps page numbers to frame numbers. When a process accesses a page not in RAM, a page fault occurs — the OS loads the page from disk.

TLB — Translation Lookaside Buffer

Looking up the page table on every memory access would be slow (it's in RAM). The TLB is a small hardware cache that stores recent virtual→physical translations, making most address translations O(1) instead of requiring a RAM lookup.

Page Replacement Algorithms

AlgorithmEvictsNotes
FIFOOldest loaded pageSimple; Bélády's anomaly — more frames can cause more faults
LRULeast Recently UsedGood in practice; expensive to implement exactly
OptimalPage used furthest in the futureTheoretical best; impossible in practice (need to know future)
Clock (LRU approx)Page with reference bit = 0Used in real OS; efficient approximation of LRU

Synchronisation — Race Conditions & Locks

When two threads share memory, they can create a race condition — the result depends on execution order. The classic example: two threads both read, increment, and write a counter. Without synchronisation, increments are lost.

Solutions: mutex (mutual exclusion lock) — only one thread holds the lock at a time; semaphore — allows N threads to enter a critical section; monitor — a higher-level abstraction combining a mutex with a condition variable.

// Concept (pseudocode)
mutex.lock()
// critical section — only one thread here at a time
counter++
mutex.unlock()

// Semaphore — limits concurrent access (e.g., connection pool of 10)
semaphore = Semaphore(10)
semaphore.wait()   // decrement; block if 0
// use connection
semaphore.signal() // increment; wake a waiting thread

Deadlocks

A deadlock occurs when two or more processes are each waiting for a resource held by the other, forming a cycle — and none can proceed. All four conditions must hold simultaneously for a deadlock to occur.

ConditionMeaning
Mutual ExclusionAt least one resource is non-shareable (only one process at a time)
Hold and WaitA process holds at least one resource while waiting for more
No PreemptionResources can't be forcibly taken; processes release voluntarily
Circular WaitA cycle: P1 waits for P2's resource, P2 waits for P1's resource

Prevention: break one condition — e.g., require processes to request all resources at once (eliminates Hold and Wait), or impose a total ordering on resource acquisition (eliminates Circular Wait).

Detection and recovery: let deadlocks happen, detect them using a resource allocation graph, then resolve by killing a process or preempting a resource.

File Systems

A file system organises data on storage devices into a hierarchy of files and directories. The OS provides a uniform interface regardless of whether storage is SSD, HDD, or network-attached.

Unix file systems use inodes — data structures that store file metadata (permissions, size, timestamps, data block pointers) but not the filename. The filename-to-inode mapping is stored in the directory. This design allows hard links (multiple filenames pointing to the same inode).

ConceptDescription
inodeFile metadata + pointers to data blocks; identified by inode number
Hard linkAnother directory entry pointing to the same inode (shared data)
Soft link (symlink)A file containing the path to another file (breaks if target deleted)
JournalingLog writes before executing; recover to consistent state after crash (ext4, NTFS)

Key Takeaways

  • A process is isolated (own memory); a thread shares memory with siblings — concurrency is powerful but requires synchronisation.
  • Round Robin with a good time quantum is the most common scheduling basis in real OS kernels.
  • Virtual memory allows programs to use more memory than physically available via paging and demand loading.
  • Deadlock requires all four conditions; break any one to prevent it. Consistent lock ordering is the most practical fix.
  • LRU is the de-facto page replacement choice; real OS use the Clock algorithm as an efficient approximation.