OS
OS
An *Operating System (OS)* is a software layer that acts as an intermediary between the hardware of a
computer and the user. Its primary function is to manage the computer's resources, such as the CPU,
memory, storage devices, and input/output devices, in an efficient manner. The OS ensures that the
system operates smoothly and provides a user-friendly environment for running applications. It also
manages file systems, security, multitasking, and hardware devices. In essence, it acts as a manager that
allocates resources, schedules tasks, and provides various services to both the user and the applications.
Operating systems have evolved over time to become more powerful, user-friendly, and capable of
managing complex tasks. These evolutionary stages are known as *Generations of Operating Systems*.
Each generation represents a significant advancement in the OS’s capabilities.
There are various types of operating systems, each designed to serve a different purpose and meet the
needs of specific hardware or software environments. Some of the common types include:
- *Batch Operating Systems*: These OSes execute jobs without user interaction. Jobs are grouped
together and processed in batches.
- *Example*: Early IBM systems.
- *Time-Sharing Operating Systems*: These systems allow multiple users to share the computer’s
resources by providing a time slice for each task. This makes the system responsive for users interacting
simultaneously.
- *Example*: UNIX.
- *Real-Time Operating Systems (RTOS)*: These are designed for applications where timely and
predictable responses are crucial, such as embedded systems, robotics, and medical devices.
- *Example*: VxWorks.
- *Distributed Operating Systems*: These OSes manage a group of separate computers that appear as a
single system to users. They coordinate multiple machines working together.
- *Example*: Google’s Android and Hadoop-based systems.
- *Network Operating Systems*: These OSes are designed to manage network resources, such as file
sharing, network communication, and device sharing.
- *Example*: Novell NetWare, Microsoft Windows Server.
- *Mobile Operating Systems*: OS designed for smartphones, tablets, and other portable devices.
- *Example*: iOS, Android.
- *Multiprocessing Operating Systems*: These systems manage the use of multiple processors in a
computer, where multiple processors execute tasks simultaneously.
- *Example*: UNIX and Linux in multi-processor configurations.
An operating system provides several services to both users and applications to ensure the efficient
functioning of the system. These services include:
- *Process Management*: This includes creating, scheduling, and terminating processes. The OS
manages process states and controls the execution of programs.
- *Memory Management*: The OS allocates and deallocates memory to processes and ensures that
each process has enough memory to execute. It also handles virtual memory, which allows processes to
use more memory than physically available.
- *File System Management*: The OS organizes files into directories and manages file access, creation,
deletion, and modification. It ensures the integrity of files and supports different file types and
permissions.
- *Device Management*: The OS communicates with hardware devices through drivers and manages
their usage. It provides a unified interface to interact with various peripheral devices such as printers,
disk drives, and display monitors.
- *Security Services*: The OS enforces policies to protect the system from unauthorized access,
providing user authentication, access control, and encryption services. It ensures that only authorized
users can execute certain actions or access specific data.
- *User Interface Services*: The OS offers user interfaces, such as command-line interfaces (CLI) or
graphical user interfaces (GUI), allowing users to interact with the system easily. These services make it
possible to execute commands, run programs, and manage system resources.
In summary, operating systems are fundamental for the functioning of computers, offering diverse
services to ensure that hardware resources are effectively utilized and that users and applications can
interact with the system in an organized manner.
### *Processes:*
- *Parent and Child Processes: A process that creates another is called a *parent process, and the newly
created process is called a child process. In many systems, a process can create multiple child processes.
- *Sibling Processes: Processes that share the same parent are called *sibling processes.
- *Independent and Co-operative Processes*:
- *Independent processes* do not share data and do not affect one another’s execution.
- *Co-operative processes* may need to share data and resources, and may coordinate their actions
(e.g., inter-process communication).
1. *New*: The process is being created. It has just been started and is not yet admitted into the ready
queue.
2. *Ready*: The process is in memory, waiting for CPU time to execute. It is ready to run, but the
operating system has not yet allocated the CPU.
3. *Running*: The process is currently being executed by the CPU. It has been allocated CPU time and is
performing its tasks.
4. *Blocked (Waiting)*: The process cannot continue because it is waiting for some event or resource,
such as I/O completion or availability of a file.
5. *Terminated (Exit)*: The process has finished execution or was killed by the OS. The operating system
removes its resources and terminates it.
1. *New → Ready*: When a process is created and placed in memory, it enters the ready state.
2. *Ready → Running*: The process is assigned CPU time and begins executing.
3. *Running → Blocked*: A process may be blocked if it needs to wait for an I/O operation to complete
or for some other event.
4. *Blocked → Ready*: Once the event the process was waiting for occurs, it moves back to the ready
state to wait for CPU allocation.
5. *Running → Terminated*: After the process finishes its execution, it is terminated, and its resources
are cleaned up by the OS.
6. *Ready → Running*: Once the process is chosen by the scheduler, it starts executing.
- *Process State*: The current state of the process (ready, running, blocked, etc.).
- *Program Counter*: The address of the next instruction to be executed by the process.
- *CPU Registers*: The values of the CPU registers that were in use when the process was last
scheduled.
- *Memory Management Information*: Information about the process’s memory allocation, such as
base and limit registers or page tables.
- *Scheduling Information*: Data related to process priority, scheduling queue, etc.
- *I/O Status Information*: Information about the devices assigned to the process and the list of files
opened by the process.
- *Process ID (PID)*: A unique identifier assigned to each process by the operating system.
- The OS saves the context of the currently running process in its PCB and loads the context of the next
scheduled process.
- Context switching is crucial for multitasking and enables the OS to manage multiple processes by giving
each one a share of CPU time.
---
### *Thread:*
1. *New*: The thread is created but has not started execution yet.
2. *Runnable*: The thread is ready to run and can be scheduled to use the CPU. This is the state when
the thread is waiting for CPU time.
3. *Blocked*: The thread is waiting for an event, such as I/O completion or synchronization, before it
can continue execution.
4. *Terminated*: The thread has finished execution and is terminated.
2. *Kernel-Level Threads*:
- Managed directly by the operating system kernel.
- The kernel is aware of the threads and schedules them for execution.
- Example: Threads in modern operating systems like Linux, Windows.
3. *Hybrid Threads*:
- A combination of user-level and kernel-level threads.
- Some threads are managed by the user application, while others are handled by the kernel.
- Example: Solaris operating system.
#### *Multithreading*
*Multithreading* is the ability of a CPU, or a single core in a multi-core processor, to provide multiple
threads of execution concurrently. Multithreading improves the performance of applications by
performing multiple operations simultaneously within the same process. It is widely used in applications
that require concurrent processing, such as web servers, games, and real-time systems.
- *Preemptive Multithreading*: The operating system's scheduler decides when to switch between
threads. Each thread is given a fixed time slice to run.
- *Cooperative Multithreading*: The threads voluntarily yield control to the scheduler or to other
threads. This type of scheduling is less common.
In summary, threads help improve the efficiency of processes by enabling concurrent execution of tasks,
and understanding their states and management is crucial for building responsive and efficient systems.
### *Process Scheduling*
*Process Scheduling* refers to the method by which an operating system decides which process (among
many) should be allocated CPU time at any given moment. The OS uses scheduling algorithms to
determine the order in which processes are executed. The goal is to maximize CPU utilization, minimize
wait time, and ensure fair process execution, depending on the operating system’s objectives.
1. *Maximizing CPU Utilization*: The system should keep the CPU busy as much as possible. High CPU
utilization ensures the system is working efficiently.
2. *Fairness*: Every process must get a fair share of CPU time, preventing any process from
monopolizing resources.
3. *Maximizing Throughput*: Throughput refers to the number of processes that are completed in a
given amount of time. The OS should try to maximize the rate at which processes are completed.
4. *Minimizing Turnaround Time*: Turnaround time is the total time taken from the submission of a
process to its completion. Scheduling algorithms aim to reduce this time.
5. *Minimizing Waiting Time*: Waiting time refers to the total time a process spends in the ready queue
waiting for CPU allocation. Reducing waiting time helps to make the system more responsive.
6. *Minimizing Response Time*: For interactive systems, response time is the time from when a user
submits a request until the system responds. The goal is to make response time as short as possible for
better user experience.
Schedulers are responsible for deciding which process to execute at any given time. There are three
main types of schedulers:
3. *Medium-Term Scheduler*:
- The medium-term scheduler controls the movement of processes between the ready queue and
blocked queue or from the main memory to secondary memory (i.e., swapping). It balances the load in
the system.
- It runs occasionally and handles processes in a swapped state, ensuring optimal use of memory.
1. *CPU Utilization*:
- CPU utilization is a measure of how effectively the CPU is being used. The goal is to maximize CPU
utilization, ideally close to 100%. For most systems, the target is to keep CPU utilization high while
avoiding the system being overwhelmed with processes.
2. *Throughput*:
- Throughput refers to the number of processes completed in a given period of time. A higher
throughput means the system can execute more processes, increasing overall productivity.
3. *Turnaround Time*:
- Turnaround time is the total time elapsed from the submission of a process until its completion. It
includes the time spent in the ready queue, waiting time, and execution time. The aim is to minimize
turnaround time to ensure timely completion of processes.
4. *Waiting Time*:
- Waiting time is the total time a process spends waiting in the ready queue before getting executed.
Reducing waiting time is crucial for improving the performance of the system.
5. *Response Time*:
- Response time is the amount of time it takes for the system to respond to a user’s request. In
interactive systems, it is a critical performance measure as users expect fast responses. Lower response
time leads to a better user experience.
Scheduling algorithms are designed to decide the order in which processes are executed. They can be
classified into two broad categories: *Pre-emptive* and *Non-pre-emptive*.
### *Conclusion*
Process scheduling plays a critical role in optimizing the performance of an operating system. It helps in
maximizing CPU utilization and throughput while minimizing waiting time, turnaround time, and
response time. The choice of scheduling algorithm depends on the specific needs of the system,
whether it’s to ensure fairness (as with Round Robin) or to minimize process completion time (as with
Shortest Job First). Each algorithm has its strengths and weaknesses, which makes it important to
choose the right one based on the application and environment.
### *Inter-process Communication (IPC)*
Inter-process communication (IPC) refers to the mechanisms that allow processes to communicate and
synchronize with each other. Since processes are generally independent and have their own memory
spaces, IPC is crucial for processes to exchange data, coordinate their actions, and ensure that shared
resources are managed efficiently.
IPC mechanisms include shared memory, message passing, semaphores, and monitors, among others.
To ensure proper communication, several synchronization issues must be handled, including race
conditions, critical sections, and mutual exclusion.
In the context of concurrency, ensuring that critical sections are executed by only one process at a time
is fundamental for correct program execution.
Example: If two processes simultaneously try to update a shared bank account balance, the result might
depend on the order of execution, leading to errors.
*Solution*: This can be solved using semaphores to synchronize access to the shared buffer:
- A *mutex* for mutual exclusion when accessing the buffer.
- A *semaphore* to track the number of empty and full slots in the buffer.
### *Semaphores*
An *event counter* is used to track the occurrence of events in a system. Each time an event occurs, the
event counter is incremented. Event counters are often used in synchronizing processes that need to
coordinate based on specific events or conditions. Event counters can be implemented using
semaphores or shared variables.
### *Monitors*
A *monitor* is a higher-level synchronization construct that provides a safer and more structured way
to handle mutual exclusion. A monitor encapsulates shared data and the procedures that operate on
them. Only one process can execute inside a monitor at a time, ensuring mutual exclusion.
Monitors are often used in combination with condition variables, which allow processes to wait for
specific conditions to be met within the monitor.
Monitors abstract the low-level details of synchronization, making them easier to use than semaphores
for some applications.
Message passing provides a way to synchronize processes and share data without relying on shared
memory, which can be beneficial in distributed environments.
Several classical IPC problems illustrate the challenges of process synchronization and communication.
Here are some well-known examples:
In the *reader-writer problem*, multiple readers and writers access a shared resource, such as a
database, with the following rules:
- *Readers* can read the data concurrently, but they should not read while the writer is updating the
data.
- *Writers* can only write when no readers are accessing the data.
The problem involves ensuring that multiple readers can access the shared resource simultaneously, but
only one writer can access it at a time, and there must be proper synchronization to prevent conflicts.
*Solution*: Semaphores or monitors can be used to enforce mutual exclusion and to coordinate
between readers and writers. A common solution is to give preference to either readers or writers to
avoid starvation.
The *dining philosophers problem* is a classic synchronization problem involving a set of philosophers
sitting at a table, each with a fork between them. Philosophers alternate between thinking and eating,
but they need both forks to eat. If two philosophers pick up the same fork simultaneously, a deadlock
occurs, and no one can eat.
*Solution*: This problem is typically solved using semaphores, mutexes, or monitors to control access to
the forks. Strategies include limiting the number of philosophers who can attempt to eat at the same
time or using a waiter (a monitor or semaphore) to avoid deadlock by ensuring that philosophers pick up
forks in a specific order.
### *Summary of IPC Problems*
### *Conclusion*
Inter-process communication is essential for the effective coordination of processes in both single-
processor and multi-processor systems. By solving problems like the producer-consumer problem, the
reader-writer problem, and the dining philosophers problem, operating systems ensure efficient
synchronization and resource sharing between processes. Techniques like semaphores, message
passing, monitors, and event counters are fundamental to achieving synchronization and mutual
exclusion in modern OS environments.
### *Deadlocks*
A *deadlock* is a situation in a concurrent system where a set of processes are blocked because each
process is holding a resource and waiting for another resource held by another process. Deadlocks lead
to a situation where no process can proceed, and system resources are effectively "locked," resulting in
a system halt or severe performance degradation.
For a deadlock to occur in a system, *four necessary conditions* must be simultaneously present. These
are:
1. *Mutual Exclusion*:
- At least one resource must be held in a non-shareable mode. That is, only one process can use a
resource at any given time.
3. *No Preemption*:
- Resources cannot be forcibly taken from processes holding them. In other words, a resource can only
be released voluntarily by the process holding it.
4. *Circular Wait*:
- A set of processes must exist such that each process in the set is waiting for a resource held by the
next process in the set. This forms a circular chain of waiting processes.
These four conditions together are necessary for deadlock to occur. If any one of these conditions is
broken, deadlock cannot happen.
Deadlock prevention and avoidance are techniques designed to avoid or minimize the occurrence of
deadlocks in a system. These methods are based on different strategies to break or avoid one of the four
necessary conditions for deadlock.
#### *Deadlock Prevention*
Deadlock prevention aims to eliminate at least one of the four necessary conditions for deadlock to
occur. Below are the approaches used to prevent each condition:
3. *Eliminate No Preemption*:
- If a process is holding resources and is waiting for additional resources, the system can preempt (take
away) some of its resources. The preempted resources are then allocated to other processes that are
waiting. Afterward, the preempted process can be restarted with the remaining resources it holds.
Deadlock avoidance is more dynamic than prevention and involves analyzing the current state of
resource allocation to ensure that a circular wait cannot occur. The key idea is to make decisions about
resource allocation based on whether the system will enter a safe or unsafe state.
The *Banker's Algorithm* is a popular deadlock avoidance algorithm used in systems where processes
request resources dynamically.
The *Banker's algorithm* is a resource allocation and deadlock avoidance algorithm that allocates
resources to processes only if it is safe to do so. It works by simulating resource allocation for each
process and checking if the system will remain in a safe state.
- *Safe State*: A state is considered safe if there exists a sequence of processes that can all be
completed without causing a deadlock. This means that all processes can finish with the available
resources.
- *Unsafe State*: A state is unsafe if no such sequence of processes exists, and deadlock is likely to occur
if resources are allocated.
The Banker's algorithm checks if a process's resource request can be granted immediately without
leading to an unsafe state. If granting a request leads to an unsafe state, the request is denied, and the
process must wait.
The key steps in the Banker's algorithm are:
1. Check if the requested resources are available.
2. Simulate the allocation of requested resources and determine if the system will be in a safe state
afterward.
3. If the system remains in a safe state, the request is granted. If not, the request is denied.
In contrast to prevention and avoidance, deadlock detection allows the system to enter an unsafe state
and then detects deadlocks when they occur. The system will take action to recover from deadlock once
it has been detected.
Deadlock detection involves checking whether the system is in a deadlock state and identifying which
processes are involved. This is typically done by using a *Resource Allocation Graph (RAG)* or *Wait-for
Graph*.
2. *Wait-for Graph*:
- A simplified version of the RAG is the *Wait-for Graph*, which only tracks processes and the
resources they are waiting for. If there is a cycle in the Wait-for Graph, deadlock is detected.
Once deadlock is detected, recovery techniques must be used to break the deadlock and allow the
system to continue functioning.
1. *Process Termination*:
- One or more processes involved in the deadlock can be terminated. This could be done in two ways:
- *Terminate all deadlocked processes*: This ensures that the deadlock is broken, but it might lead to
a loss of all work done by the terminated processes.
- *Terminate one process at a time*: A process is terminated, and the system checks whether the
deadlock is resolved. If not, another process is terminated.
2. *Resource Preemption*:
- Resources can be forcibly taken from some processes and reassigned to others. This can break the
circular wait, but it can also lead to further issues, such as starvation (where some processes never get
their resources).
### *Conclusion*
Deadlocks are a critical issue in multi-process systems, where processes compete for shared resources.
To handle deadlocks, operating systems can use prevention, avoidance, detection, and recovery
techniques. Deadlock prevention eliminates one or more necessary conditions, while avoidance
dynamically ensures that deadlock will not occur. Detection and recovery techniques detect deadlock
after it occurs and work to resolve it. Each technique has its trade-offs in terms of complexity,
performance, and system safety, and the choice of technique depends on the specific system
requirements and constraints.
### *Memory Management in Operating Systems*
Memory management is a key function of an operating system (OS) that manages computer memory,
which includes both the *primary memory* (RAM) and *secondary memory* (e.g., hard drives or SSDs).
The main goal of memory management is to allocate memory efficiently to various programs and
processes while ensuring proper isolation, protection, and sharing of memory space.
The OS is responsible for managing both the *logical memory* and the *physical memory*, ensuring
that different processes get the memory they need without conflicting with each other.
- *Logical Address: The address generated by the CPU during a program's execution. It is also called a
**virtual address* because it doesn't refer directly to the physical memory location.
- *Physical Address*: The actual location in the computer’s memory hardware (RAM) where data or
code is stored.
The *memory management unit (MMU)* is responsible for mapping logical addresses (generated by
processes) to physical addresses (actual locations in memory).
In a simple, non-paged memory system, the *logical address* is directly mapped to a *physical address.
However, in systems using **paging* or *segmentation, there is a complex mapping between logical
and physical addresses, typically handled by the **MMU*.
Memory allocation refers to the process of assigning portions of memory to different processes running
in the system. There are various techniques for memory allocation, and each has its own advantages and
challenges.
Contiguous memory allocation involves assigning a single contiguous block of memory to each process.
This technique is simpler but has limitations in terms of efficiency and flexibility.
#### *Fragmentation*
- *Internal Fragmentation*: Occurs when a process is allocated more memory than it actually needs,
resulting in unused space within the allocated memory block. This happens in fixed partitioning, where
the partition size is fixed, and smaller processes are allocated more memory than required.
*Example*: A process that needs 200KB is allocated a partition of 256KB, leaving 56KB of unused space
within that partition.
- *External Fragmentation*: Occurs when free memory is split into small blocks scattered throughout
the memory, making it difficult to allocate large contiguous blocks to processes. This happens in variable
partitioning, where processes are allocated different-sized blocks.
*Example*: If there are free blocks of 20KB, 50KB, and 100KB, and a new process needs 120KB of
space, it cannot be allocated because no single free block is large enough, even though the total free
space is enough.
#### *Compaction*
*Compaction* is a technique used to reduce external fragmentation. It involves shifting the processes in
memory to consolidate free memory into a single block. This process can be costly in terms of time and
overhead, as it requires moving many processes in memory.
### *Paging*
Paging is a memory management scheme that eliminates the need for contiguous memory allocation
and fragmentation problems. In paging, both physical and logical memory are divided into fixed-size
blocks called *pages* (in logical memory) and *frames* (in physical memory).
When a process is executed, the operating system uses the page table to translate the process's logical
addresses (pages) to physical addresses (frames) in RAM.
*Example*:
- If a process needs to access data at logical address 0x5A and the page size is 4KB, the address will be
split into a *page number* and an *offset*. The page table will give the corresponding physical frame
for that page, and the offset will be added to this frame to get the final physical address.
Page allocation is the method used by the operating system to assign physical memory frames to the
pages of a process. The page table holds the mapping between the pages of a process and the frames of
physical memory.
In the *paging system*, the allocation of memory is non-contiguous, meaning that different pages of a
process can be stored in different frames across the physical memory. This helps reduce fragmentation
and allows efficient use of memory.
To implement paging efficiently, the hardware (specifically, the *Memory Management Unit (MMU)*)
supports features such as:
- *Page Table*: A data structure that stores the mapping between pages and frames.
- *Page Table Register (PTR)*: A register that points to the base address of the page table in memory.
- *TLB (Translation Lookaside Buffer)*: A small, fast cache that stores recent page table entries to speed
up address translation.
- *Page Fault Handler: When a process accesses a page that is not currently in memory (a **page
fault*), the OS must handle it by loading the page from disk into a free frame in memory.
Paging provides a straightforward way to implement *memory protection* and *sharing* between
processes.
- *Protection*: The page table can include permissions for each page (read, write, execute), ensuring
that processes cannot access pages they shouldn't (such as system or other process pages).
- *Sharing*: Multiple processes can share the same physical page. For example, a read-only code page
can be mapped into the address space of several processes, saving memory. The page table entries for
shared pages will point to the same physical frame.
### *Conclusion*
Memory management is essential for efficient process execution and resource utilization in an operating
system. Techniques such as contiguous allocation, paging, and partitioning help in managing how
processes access memory. While each method comes with its own set of advantages and challenges,
modern systems typically employ paging due to its flexibility and efficiency in handling memory
allocation without fragmentation.
### *Virtual Memory*
*Virtual Memory* is a memory management technique that provides an "idealized" abstraction of the
storage resources that are actually available on a given machine, which creates the illusion to users of a
very large (and contiguous) main memory. Virtual memory allows processes to be executed even if they
are not entirely loaded into physical memory. This is achieved by using disk space to extend the
available memory. The main goal of virtual memory is to run larger programs on systems with limited
physical memory and to facilitate multitasking by isolating processes.
Virtual memory enables a computer system to execute processes that may not be completely stored in
the physical memory (RAM) by temporarily transferring data to and from secondary storage (e.g., hard
disk or SSD). This is achieved through a combination of hardware and software mechanisms, enabling
efficient management of memory resources.
The *Memory Management Unit (MMU)* is responsible for mapping the virtual addresses used by a
program to physical addresses in the RAM.
The primary hardware component that supports virtual memory is the *Memory Management Unit
(MMU). The MMU maps virtual addresses to physical addresses using a **page table*. This enables the
OS to handle the mapping dynamically and allows for processes to be in virtual memory while executing.
*Page Table*: A data structure used to store the mapping of virtual pages to physical frames. Each
process has its own page table, and the MMU uses this table to perform the translation from virtual to
physical memory.
*Control Structures: These structures include the **page table* and the *Translation Lookaside Buffer
(TLB), which caches recent page table entries to speed up the translation process. The operating system
also maintains a **frame allocation table* to manage physical memory.
Locality of reference refers to the tendency of a program to access a relatively small portion of its
address space at any given time. This concept is critical to understanding how virtual memory and
paging work effectively.
Virtual memory systems exploit these patterns by bringing in memory pages that are likely to be used
soon, improving the efficiency of memory usage.
A *page fault* occurs when a process tries to access a page that is not currently in physical memory.
This happens when the required page is not in the *main memory* but is instead stored in *secondary
storage* (e.g., disk). When a page fault occurs:
1. The operating system checks the page table to confirm that the page is indeed on disk.
2. The required page is loaded from disk into a free page frame in physical memory.
3. The page table is updated, and the instruction that caused the page fault is restarted.
Page faults are a normal part of virtual memory systems, but if they occur too frequently, it can degrade
system performance, causing what is known as *thrashing*.
The *working set* of a process is the set of pages that are actively being used by the process in the
current time period. This concept is important in memory management because it helps determine the
optimal amount of memory to allocate to each process.
- If a process's working set is larger than the available physical memory, page faults become frequent,
leading to performance degradation.
- The working set can be adjusted dynamically based on the program's behavior to minimize the number
of page faults.
A *dirty page* is a page that has been modified since it was loaded into physical memory. The *dirty
bit* is a flag associated with each page, indicating whether the page has been modified. If the dirty bit is
set, it means that the page needs to be written back to the disk before it can be swapped out of physical
memory.
When a dirty page is swapped out, the operating system must write it to disk to ensure that changes are
not lost. If the page is not dirty, it can be swapped out without any further action because the content
has not been modified.
*Demand paging* is a memory management scheme where pages are loaded into memory only when
they are needed, i.e., when a page fault occurs. This is in contrast to *pre-paging*, where pages are
loaded into memory before they are actually needed.
With demand paging, the operating system minimizes the amount of memory used by only loading the
necessary pages, which helps to optimize memory utilization. It also reduces the time spent loading
unnecessary pages into memory, improving performance.
### *Page Replacement Algorithms*
When there is no free space in physical memory and a new page needs to be loaded, one of the existing
pages in memory must be replaced. Various *page replacement algorithms* are used to determine
which page to replace when a page fault occurs.
- *Optimal Page Replacement* is the best possible page replacement algorithm because it always
selects the page that will not be used for the longest period of time in the future.
- *How it works*: When a page fault occurs, the OS looks ahead to see which page will not be used for
the longest period of time and replaces it.
- *Disadvantages*: It is difficult to implement in practice because it requires knowledge of future
memory references, which is not available.
- *FIFO* is one of the simplest page replacement algorithms. It replaces the oldest page in memory,
regardless of how frequently or recently it has been accessed.
- *How it works*: The OS keeps track of the order in which pages were loaded into memory and
replaces the oldest page when a new page needs to be loaded.
- *Disadvantages*: FIFO often performs poorly because it does not take into account how often or
recently a page was used. A page that has been in memory the longest may still be actively used.
- *LRU* is a page replacement algorithm that replaces the page that has not been used for the longest
period of time. It attempts to exploit the principle of *temporal locality* by assuming that pages that
have been used recently will likely be used again soon.
- *How it works*: The OS keeps track of the time when each page was last accessed, and when a page
needs to be replaced, it replaces the least recently used page.
- *Disadvantages*: Implementing LRU can be complex because it requires keeping track of access times
for all pages in memory. It may also incur overhead in maintaining this information.
Virtual memory is a crucial feature in modern operating systems that allows the execution of larger
programs and multitasking in systems with limited physical memory. It utilizes concepts such as paging,
demand paging, and page replacement algorithms to manage memory efficiently. While algorithms like
Optimal, FIFO, and LRU each have their own trade-offs in terms of complexity and performance, they all
aim to optimize memory usage and reduce the impact of page faults on system performance.
### *File Management*
File management refers to the process of storing, retrieving, and managing files on a computer system.
It includes a range of activities, such as organizing files, tracking file attributes, allocating space for files,
and ensuring access control.
A *file* is a collection of data or information that is stored on a storage medium such as a hard disk,
SSD, or optical disk. It has a name, a type, and attributes such as size, creation date, and access
permissions. Files are fundamental units of data storage and are used by applications and the operating
system for storing user data, program code, and system data.
The *access method* refers to the way data is read from or written to a file. The main file access
methods are:
1. *Sequential Access*: Data is read or written in a sequential order, from the beginning to the end. This
is the most basic method, used by text files.
2. *Direct Access (Random Access)*: Data can be read or written in any order. This allows efficient
access to large files, such as database files or multimedia files.
3. *Indexed Access*: An index is maintained to allow efficient access to different parts of a file. This is
often used in databases.
Files can be classified based on their content or usage. Some common file types include:
- *Text Files*: Human-readable data.
- *Executable Files*: Contain machine code that can be executed by the operating system.
- *Directory Files*: Contain information about other files and directories.
- *Device Files*: Represent devices in the system (e.g., printers, disk drives).
The directory structure defines how files and directories are organized within the file system. The
directory structure can be:
1. *Single-level Directory*: All files are stored in one directory.
2. *Two-level Directory*: There are separate directories for each user, and files are stored in those
directories.
3. *Hierarchical Directory*: Files are organized in a tree-like structure, where directories can contain
subdirectories, leading to a more complex and organized file structure.
4. *Networked Directory*: Used in networked systems where files are shared across different machines.
A *file system* is a method of organizing and storing files on a storage medium. It includes:
1. *File Control Block (FCB)*: Contains metadata about the file, such as its name, location, and size.
2. *Directory Structure*: Organizes files into directories and subdirectories.
3. *File Allocation Table (FAT)*: A table that keeps track of where the file's data is stored on the disk.
1. *Contiguous Allocation*:
- Files are stored in a continuous block of memory.
- *Advantages*: Simple to implement, fast access.
- *Disadvantages*: Leads to fragmentation (both internal and external) as files are added and
removed.
2. *Linked Allocation*:
- Files are stored in non-contiguous blocks, and each block contains a pointer to the next block.
- *Advantages*: Eliminates external fragmentation, allows dynamic file sizes.
- *Disadvantages*: Slower access due to the need to follow pointers.
3. *Indexed Allocation*:
- An index block is used to store pointers to the data blocks of the file. Each file has its own index
block.
- *Advantages*: No fragmentation, faster access than linked allocation.
- *Disadvantages*: Additional overhead due to the index block, can waste space if file sizes are small.
The efficiency and performance of a file system depend on several factors, including the allocation
method, the type of access method, disk speed, and the file system structure. Contiguous allocation is
fast but leads to fragmentation. Linked allocation avoids fragmentation but has slower access. Indexed
allocation strikes a balance but requires extra memory for the index block.
Disk scheduling refers to the methods used to decide the order in which disk I/O requests are served.
The goal is to minimize seek time (time spent moving the disk head).
1. *First-Come-First-Served (FCFS)*:
- Requests are served in the order they arrive.
- *Disadvantages*: Can lead to inefficient use of the disk (e.g., long seeks).
3. *SCAN*:
- The disk arm moves in one direction, servicing requests until it reaches the end, then reverses
direction.
- *Disadvantages*: Can cause unequal wait times for requests near the ends.
Disk reliability refers to the ability of the disk to store data without failure. Reliability is typically
measured by the *Mean Time Between Failures (MTBF). The disk also uses **redundancy* and *parity*
to protect against data loss.
Disk formatting prepares the disk for use by creating a file system. This includes:
- *Low-level formatting*: Dividing the disk into sectors and tracks.
- *High-level formatting*: Creating the file system structure, including the allocation tables and
directories.
#### *Boot Block*
The *boot block* is the section of a disk or storage device that contains the code to load the operating
system. It is read by the computer’s firmware during the boot process to initiate the operating system.
*Bad blocks* are sectors on a disk that are damaged or unreliable. Disk management systems track
these bad blocks and avoid allocating them for storing data.
---
---
In summary, each of these operating systems has its strengths, and the choice depends on the specific
use case, whether it’s for servers (UNIX, Linux) or personal computing (Windows).