Operating Systems: Process Management and Memory Allocation
Table of Contents
- Core and CPU
- Processes
- Process Cycle
- More on Process States
- Stack and Heap Memory
- Dynamic Memory Allocation: Malloc and Calloc
- Summary
Core and CPU
Understanding the CPU
The Central Processing Unit (CPU) is the core component of a computer responsible for executing instructions. It carries out arithmetic, logic, control, and input/output (I/O) operations. CPUs manage multiple processes and execute instructions sequentially or in parallel if the system supports multi-core processing.
The CPU consists of:
- Arithmetic Logic Unit (ALU): Performs mathematical and logical operations.
- Control Unit (CU): Directs operations within the processor.
- Registers: Small storage units that hold data and instructions during execution.
- Cache: Fast memory located inside the CPU to speed up access to frequently used data.
Cores in a CPU
A core is an individual processing unit within a CPU capable of executing instructions independently. Modern CPUs are multi-core, meaning they have multiple cores to enhance performance through parallel processing.
- Single-core CPUs process one instruction at a time.
- Multi-core CPUs (dual-core, quad-core, octa-core) can handle multiple tasks simultaneously.
- Hyper-threading (Intel) and Simultaneous Multi-threading (AMD) allow a single core to execute multiple threads efficiently.
Each core can execute one process at a time, but with multi-threading and scheduling, multiple threads can share execution time.
Processes
A process is an active instance of a program running on a computer. It represents an execution unit that the operating system manages.
Key Characteristics of Processes
- Processes are allocated system resources, including memory and CPU time.
- Each process has its own memory space to prevent interference between programs.
- Processes are created and terminated dynamically, meaning they start when needed and close upon completion.
- Multiple processes can run simultaneously, managed by the OS scheduler.
Threads vs. Processes
- A process is an independent execution unit with dedicated system resources.
- A thread is a smaller execution unit within a process that shares the same memory space.
- Multi-threading allows a single process to perform multiple tasks concurrently.
Process Cycle
A process moves through different states during execution:
- New: The process is created but not yet scheduled.
- Ready: The process is waiting for CPU time.
- Running: The process is actively executing on the CPU.
- Waiting: The process is waiting for an I/O operation or event to complete.
- Terminated: The process has completed execution and is removed from memory.
Key Transitions Between Process States
- Admitted: Moves from New → Ready when it is loaded into memory.
- Scheduler Dispatch: Moves from Ready → Running when the CPU starts execution.
- Interrupt: A running process moves to Ready when preempted by another process.
- I/O Wait: Moves from Running → Waiting if an I/O operation is requested.
- I/O Completion: Moves from Waiting → Ready once I/O is complete.
- Exit: Moves from Running → Terminated once execution finishes.
The OS scheduler ensures that processes transition efficiently between states.
More on Process States
Ready Queue
- Stores processes waiting for CPU time.
- When the CPU becomes available, the scheduler selects a process from the Ready Queue.
Running State
- A process actively executing instructions on the CPU.
- Can transition to Completed after execution or move to Waiting if blocked by an I/O operation.
Waiting Queue
- Processes in Waiting are blocked and awaiting resources.
- They return to Ready once resources become available.
State Transitions and CPU Scheduling
- Waiting → Ready: Triggered when an I/O operation is complete.
- Running → Waiting: Occurs when an I/O operation is requested.
- Running → Completed: Process finishes execution successfully.
Device Controllers and I/O
- The CPU communicates with devices (disk, keyboard, printer) through device controllers.
- Interrupts notify the CPU when an I/O operation completes.
Key Concepts
- Context Switching: The CPU switches between processes to allow multitasking.
- Interrupt Handling: Ensures the CPU responds to external events efficiently.
Stack and Heap Memory
Understanding the Process Memory Layout
A process’s memory is divided into distinct sections:
- Text Segment (Code): Stores program instructions.
- Data Segment:
- Initialized Data: Global/static variables with defined values.
- Uninitialized Data (BSS): Global/static variables initialized to zero.
- Heap: Dynamically allocated memory that grows upwards.
- Stack: Stores function calls, local variables, and control data. It grows downwards.
The Stack
- The stack follows a Last In, First Out (LIFO) structure.
- Each function call creates a stack frame consisting of:
- Function arguments
- Return address
- Local variables
Example of Stack Usage in C
void fn(int a) {
a += 1; // Local variable stored in the stack
}
int main() {
int local = 10;
fn(local); // Stack frame created for 'fn' function call
return 0;
}
Each function call pushes a new frame onto the stack, and upon completion, it pops the frame, returning to the previous function.
Stack Overflow
If too many function calls occur without returning (e.g., infinite recursion), the stack can overflow, causing a program crash.
Dynamic Memory Allocation: Malloc and Calloc
Understanding Heap Memory
The heap is used for dynamic memory allocation, where memory is allocated at runtime instead of compile time. It grows upwards and requires explicit deallocation to avoid memory leaks.
malloc()
- Allocates a single block of memory.
- Does not initialize memory (contains garbage values).
- Returns a void pointer to the allocated memory.
Example:
int *arr = (int*)malloc(5 * sizeof(int)); // Allocates memory for 5 integers
calloc()
- Allocates memory for an array of elements.
- Initializes memory to zero.
- Returns a void pointer to the allocated memory.
Example:
int *arr = (int*)calloc(5, sizeof(int)); // Allocates and initializes memory for 5 integers
Key Differences Between malloc() and calloc()
- malloc() provides uninitialized memory.
- calloc() initializes allocated memory to zero.
- calloc() takes two parameters (num, size), whereas malloc() takes only one (size).
Memory Leaks and Deallocation
- Memory leaks occur when dynamically allocated memory is not released.
- Always free memory after use to prevent leaks.
Example of free():
free(arr); // Deallocates dynamically allocated memory
Summary
This guide provides a deep dive into process management, CPU execution, and memory allocation. Key takeaways include:
- Processes and their states: Ready, Running, Waiting, Terminated.
- CPU scheduling and context switching for efficient multitasking.
- Stack and heap memory allocation, along with common pitfalls.
- Dynamic memory allocation using
malloc()
andcalloc()
.
Understanding these concepts is crucial for optimizing system performance and preventing memory-related issues.