UNIT-II-OS
UNIT-II-OS
1. Process Concept:
A process is an instance of a program that is being executed by a computer. The operating System
helps you to create, schedule and terminates the processes which is used by CPU. A process created
by the main process is called a child process. Process operations can be easily controlled with the
help of Process Control Block (PCB). PCB is the brain of the process, which contains all the crucial
information related to processing like Process ID, priority, State, CPU registers, etc.,
Process Structure:
When a Program is loaded into the memory and it becomes a process, it can be divided into four
sections- Stack, Heap, Data and Text.
Stack: The process contains the temporary 0 data such as method/function, parameters, return
address and local variables.
Heap: This is dynamically allocated memory to a process during its runtime.
Data: This section contains the global and static variables.
Text: This includes the current activity represented by the value of program counter and the
contents of the processor’s registers.
Process states:
A process state is a condition of the process at a specific instance of time, It also defines the current
position of the process.
There are mainly seven stages of a process which are:
New: The new process is created when a specific program calls from Secondary memory/hard disk
to Primary memory/RAM are made.
Ready: In ready state, the process should be loaded into the primary memory, which is ready for
execution.
Waiting: The process is waiting for the allocation of CPU time and other resources for execution.
Executing: The process is an execution state.
Blocked: It is a time interval when a process is waiting for an event like I/O operations to complete.
Suspended: Suspended state defines the time when a process is ready for execution but has not
been placed in the ready queue by OS.
Terminated: Terminated state specifies the time when a process is terminated.
Process Control Block
Every process is represented in the operating system by a process control block, which is also called
a Task Control Block.
Process Identifier (PID): A unique number assigned to each process for identification.
Process State: The current state of the process (e.g., new, ready, running, waiting, or
terminated).
Program Counter: The address of the next instruction to be executed.
CPU Registers: The contents of the CPU registers used by the process.
Accounting and Business Information: It includes the amount of CPU and time utilities like
real time used job or process numbers, etc.
Memory Management Information: Details about the memory allocated to the process
(e.g., base and limit registers, page tables).
Scheduling Information: Information needed by the scheduler, such as priority, process ID,
and scheduling queues.
I/O Status Information: Information about the I/O devices assigned to the process.
2. Process Scheduling
Process scheduling is an essential part of multiprogramming OS. That type of OS allows more than
one process to be loaded into the executable memory at a time and the process loaded. It is the
activity of the process manager. It handles the removal of the running process from the CPU. OS
maintains all PCB in process scheduling queues. OS maintains a separate Queue for each of the
process states and PCB for all processes. Processes are in same execution state are placed in the
same queue.
3. Operations on Processes
Mainly we can perform two operations on the processes.
1. Process Creation
2. Process Termination
1. Process Creation
A process may create several new processes. The creating process is called a parent process, and
the new processes are called the children of that process. Each of these new processes may in turn
create other processes, forming a tree of processes. Most operating systems identify processes
according to a unique process identifier (or pid), which is typically an integer number. The pid provides
a unique value for each process in the system.
A process terminates when it finishes executing its final statement and asks the operating
system to delete it by using the exit() system call. At that point, the process may return a status value
(typically an integer) to its parent process (via the wait() system call). All the resources of the process—
including physical and virtual memory, open files, and I/O buffers—are deallocated by the operating
system.
If a process terminates (either normally or abnormally), then all its children must also be
terminated. This phenomenon, referred to as cascading termination, is normally initiated by the
operating system. To illustrate process execution and termination, consider that, in Linux and UNIX
systems, we can terminate a process by using the exit() system call, providing an exit status as a
parameter:
/* exit with status 1 */
exit(1);
A parent process may wait for the termination of a child process by using the wait() system call. The
wait() system call is passed a parameter that allows the parent to obtain the exit status of the child.
This system call also returns the process identifier of the terminated child so that the parent can tell
which of its children has terminated:
pid t pid;
int status;
pid = wait(&status);
When a process terminates, its resources are deallocated by the operating system.
4. Inter-process Communication
It is the mechanism provided by the OS that allows processes to communicate with each other.
It is used for exchanging useful information between numerous threads in one or more processes.
There are several reasons for providing an environment that allows process cooperation:
• Information sharing. Since several users may be interested in the same piece of information (for
instance, a shared file), we must provide an environment to allow concurrent access to such
information.
• Computation speedup. If we want a particular task to run faster, we must break it into subtasks,
each of which will be executing in parallel with the others. Notice that such a speedup can be achieved
only if the computer has multiple processing cores.
• Modularity. We may want to construct the system in a modular fashion, dividing the system
functions into separate processes or threads, as we discussed in Chapter 2.
• Convenience. Even an individual user may work on many tasks at the same time. For instance, a
user may be editing, listening to music, and compiling in parallel.
Cooperating processes require an inter-process communication (IPC) mechanism that will allow
them to exchange data and information. There are two fundamental models of inter-process
communication: shared memory and message passing.
In the shared-memory model, it facility enables an area of memory to be shared by two or more
processes.
Processes can then exchange information by reading and writing data to the shared region. In the
message-passing model, A message includes a sequence of characters that are sent to and receive
by processes.
3) Buffering
Whether communication is direct or indirect, messages exchanged by communicating
processes reside in a temporary queue. Basically, such queues can be implemented in three
ways:
Zero capacity. The queue has a maximum length of zero; thus, the link cannot have any
messages waiting in it. In this case, the sender must block until the recipient receives the
message.
Bounded capacity. The queue has finite length n; thus, at most n messages can reside in it. If
the queue is not full when a new message is sent, the message is placed in the queue and
the sender can continue execution without waiting.
Unbounded capacity. The queue’s length is potentially infinite; thus, any number of
messages can wait in it. The sender never blocks.
Thread components
Any thread has the following components.
1. Program counter
2. Register set
3. Stack space
1. Many-To-One Model
In the many-to-one model, many user-level threads are all mapped onto a single kernel thread.
Thread management is handled by the thread library in user space, which is very efficient.
However, if a blocking system call is made, then the entire process blocks, even if the other user
threads would otherwise be able to continue.
Because a single kernel thread can operate only on a single CPU, the many-to-one model does
not allow individual processes to be split across multiple CPUs.
Green threads for Solaris and GNU Portable Threads implement the many-to-one model in the
past, but few systems continue to do so today.
2. One-To-One Model
The one-to-one model creates a separate kernel thread to handle each user thread.
One-to-one model overcomes the problems listed above involving blocking system calls and the
splitting of processes across multiple CPUs.
However the overhead of managing the one-to-one model is more significant, involving more
overhead and slowing down the system.
Most implementations of this model place a limit on how many threads can be created.
Linux and Windows from 95 to XP implement the one-to-one model for threads.
3. Many-To-Many Model
The many-to-many model multiplexes any number of user threads onto an equal or smaller
number of kernel threads, combining the best features of the one-to-one and many-to-one
models.
Users have no restrictions on the number of threads created.
Blocking kernel system calls do not block the entire process.
Processes can be split across multiple processors.
Individual processes may be allocated variable numbers of kernel threads, depending on the
number of CPUs present and other factors.
6. Thread Libraries
A thread library is a collection of functions that allow a program to create, manage, and synchronize
threads. These libraries provide an interface for developers to implement multithreading in applications,
enabling parallel execution and efficient resource utilization.
Thread libraries can be categorized based on the operating system and programming environment. The
major thread libraries include:
Example:
#include <pthread.h>
#include <stdio.h>
void *print_message(void *arg) {
printf("Hello from thread!\n");
return NULL;
}
int main() {
pthread_t thread;
pthread_create(&thread, NULL, print_message, NULL);
pthread_join(thread, NULL);
return 0;
}
pthread_create() → Creates a new thread.
pthread_join() → Waits for the thread to complete.
B. Windows Threads
Thread library for Windows operating systems.
Uses the Windows API for thread creation and management.
Functions include:
o CreateThread() → Creates a thread.
int main() {
HANDLE thread;
DWORD threadID;
thread = CreateThread(NULL, 0, threadFunction, NULL, 0, &threadID);
WaitForSingleObject(thread, INFINITE);
CloseHandle(thread);
return 0;
}
}
}
If exec() is called immediately after forking, then duplicating all threads is unnecessary, as the program
specified in the parameters to exec() will replace the process. In this instance, duplicating only the
calling thread is appropriate. If, however, the separate process does not call exec() after forking, the
separate
process should duplicate all threads.
b) Signal Handling
Signal Handling in Thread Issues refers to the process of managing and responding to signals
(asynchronous notifications) in multi-threaded programs. In multi-threaded applications, signals can
be delivered either to a specific thread or to the entire process, which creates challenges in
determining which thread should handle the signal. Effective signal handling ensures that signals are
processed in a controlled and predictable manner, avoiding race conditions, data corruption, or
inconsistent states. Proper management often involves using signal masks, blocking signals in
specific threads, and assigning a dedicated thread to handle signals. This process is crucial for
maintaining the stability and performance of multi-threaded applications.
c)ThreadCancellation
Thread cancellation is the process of terminating a thread before it completes its execution. This is
useful in situations where a thread is no longer needed or must be stopped due to errors, timeouts,
or shutdown conditions.
d) Thread Pools
A thread pool is a collection of worker threads that are created once and reused multiple times to
execute tasks. Instead of creating and destroying threads dynamically for every task, a thread pool
manages a fixed number of threads that can pick up tasks from a queue.
e) Thread specific Data
Thread-Specific Data (TSD) allows each thread to have its own copy of a global variable without
interfering with other threads. It is useful when multiple threads need to store and access data
independently, without sharing the same memory location.
8. CPU Scheduling
CPU Scheduling is the process of determining which process or thread should be executed by the CPU at
any given time. Since modern operating systems are multitasking, they must manage the execution of
multiple processes concurrently by switching between them. The goal of CPU scheduling is to allocate
CPU time to processes in an efficient manner while ensuring fairness and optimal system performance.
CPU scheduling algorithms are broadly categorized into two main types based on how the CPU
allocation is managed:
In preemptive scheduling, the CPU can be taken away from a running process before it
finishes, allowing other processes to be scheduled.
o Allows for better responsiveness and fairness.
o Helps prevent starvation and priority inversion if managed properly.
Examples:
o Round Robin (RR)
o Shortest Remaining Time First (SRTF)
o Multilevel Feedback Queue Scheduling
o Earliest Deadline First (EDF)
9. Scheduling Criteria
Scheduling criteria refer to the various performance metrics used to evaluate the effectiveness of a CPU
scheduling algorithm. These criteria help in comparing different algorithms to determine which one is
best suited for specific systems or workloads. The primary scheduling criteria include:
1. CPU Utilization
The percentage of time the CPU is actively executing processes. The goal is to keep the CPU
as busy as possible.
Maximize CPU utilization to ensure the system is efficiently using its resources.
2. Throughput
The number of processes completed in a given period of time.
Maximize throughput to ensure that the system performs many tasks over a short period.
3. Turnaround Time
The total time taken for a process to complete, from the time of submission to the time of
completion. It includes both the waiting time and the actual execution time.
Minimize turnaround time so that processes complete quickly, improving system efficiency.
4. Waiting Time
The total time a process spends waiting in the ready queue before it gets the CPU for
execution. It does not include the time spent executing.
Minimize waiting time to ensure processes start executing as soon as possible, reducing
delays in process completion.
5. Response Time
The time from submitting a request (or input) until the system starts responding. This metric
is particularly important for interactive systems.
Minimize response time to enhance the responsiveness of interactive systems, such as user-
facing applications.
10. Scheduling Algorithms
1. First-Come, First-Served (FCFS)
Processes are executed in the order they arrive in the ready queue (non-preemptive). Think of it like a
waiting line.
Gantt Chart:
| Process | Arrival Time | Burst Time | Priority |
| P1 |0 |7 |3 |
| P2 |2 |4 |1 |
| P3 |4 |2 |2 |
| P4 |5 |1 |4 |
| P1 | P2 | P3 | P4 |
0 7 11 13 14
* P1 arrives first, runs to completion. Then P2, then P3, then P4.
* Simple to implement.
* Can lead to long waiting times for short processes (convoy effect).
* Example: Imagine a single checkout line at a grocery store. If someone with a huge cart gets in line
first, everyone else has to wait, even if they only have a few items.
Table (FCFS):
| Process | Arrival Time | Burst Time | Completion Time | Turnaround Time (Completion - Arrival) |
Waiting Time (Turnaround - Burst) |
|---|---|---|---|---|---|
| P1 | 0 | 7 | 7 | 7 | 0 |
| P2 | 2 | 4 | 11 | 9 | 5 |
| P3 | 4 | 2 | 13 | 9 | 7 |
| P4 | 5 | 1 | 14 | 9 | 8 |
2. Shortest Job First (SJF) (Non-Preemptive)
The process with the shortest burst time is run next (non-preemptive). Requires knowing burst times in
advance.
Gantt Chart:
| Process | Arrival Time | Burst Time | Priority |
| P1 |0 |7 |3 |
| P2 |2 |4 |1 |
| P3 |4 |2 |2 |
| P4 |5 |1 |4 |
| P1 | P4 | P3 | P2 |
0 7 8 10 14
* P1 runs first. Then, P4 (shortest remaining burst), then P3, then P2.
* Optimal for minimizing average waiting time.
* Requires knowing burst times in advance (often unrealistic).
* Example: A server at a help desk might prioritize the shortest customer issues to quickly resolve them.
Table (SJF):
| Process | Arrival Time | Burst Time | Completion Time | Turnaround Time | Waiting Time |
| P1 |0 |7 |7 |7 |0 |
| P4 |5 |1 |8 |3 |2 |
| P3 |4 |2 | 10 |6 |4 |
| P2 |2 |4 | 14 | 12 |8 |
3. Round Robin (RR)
Each process gets a small time slice (quantum). If it doesn't finish in the quantum, it's preempted and
moved to the back of the ready queue.
Gantt Chart (Quantum = 2):
| P1 | P2 | P3 | P4 | P1 | P2 | P3 | P1 | P2 |
0 2 4 6 8 10 12 14 16 18
Gantt Chart (Preemptive - In this specific example, it's the same as non-preemptive because no higher-
priority process arrives while a lower-priority one is running):
| P2 | P3 | P1 | P4 |
0 4 6 13 14
* P2 (highest priority) runs first, then P3, then P1, then P4.
* Can prioritize important tasks.
* Can lead to starvation of low-priority processes.
* Example: A hospital emergency room might prioritize patients with the most life-threatening
conditions.
Table (Priority - Both Preemptive and Non-Preemptive in this case):
| Process | Arrival Time | Burst Time | Completion Time | Turnaround Time | Waiting Time |
| P2 |2 |4 |4 |2 |0 |
| P3 |4 |2 |6 |2 |0 |
| P1 |0 |7 | 13 | 13 |6 |
| P4 |5 |1 | 14 |9 |8 |
11. Multiple Processor Scheduling
When multiple processors are available, then the scheduling gets more complicated, because
now there is more than one CPU which must be kept busy and in effective use at all times.
Load sharing revolves around balancing the load between multiple processors.
Multi-processor systems may be heterogeneous, ( different kinds of CPUs ), or homogenous,
( all the same kind of CPU ). Even in the latter case there may be special scheduling
constraints, such as devices which are connected via a private bus to only one of the CPUs.
This book will restrict its discussion to homogenous systems.
Processor Affinity
Processors contain cache memory, which speeds up repeated accesses to the same memory
locations.
If a process were to switch from one processor to another each time it got a time slice, the data
in the cache ( for that process ) would have to be invalidated and re-loaded from main memory,
thereby obviating the benefit of the cache.
Therefore SMP systems attempt to keep processes on the same processor, via processor affinity.
Soft affinity occurs when the system attempts to keep processes on the same processor but
makes no guarantees. Linux and some other OSes support hard affinity, in which a process
specifies that it is not to be moved between processors.
Main memory architecture can also affect process affinity, if particular CPUs have faster access to
memory on the same chip or board than to other memory loaded elsewhere. ( Non-Uniform
Memory Access, NUMA. ) As shown below, if a process has an affinity for a particular CPU, then it
should preferentially be assigned memory storage in "local" fast access areas.
Load Balancing
Traditional SMP required multiple CPU chips to run multiple kernel threads concurrently.
Recent trends are to put multiple CPUs ( cores ) onto a single chip, which appear to the system as
multiple processors.
Compute cycles can be blocked by the time needed to access memory, whenever the needed
data is not already present in the cache. ( Cache misses. ) In Figure 5.10, as much as half of the
CPU cycles are lost to memory stall.
By assigning multiple kernel threads to a single processor, memory stall can be avoided ( or
reduced ) by running one thread on the processor while the other thread waits for memory.
A dual-threaded dual-core system has four logical processors available to the operating system.
The UltraSPARC T1 CPU has 8 cores per chip and 4 hardware threads per core, for a total of 32
logical processors per chip.
There are two ways to multi-thread a processor:
1. Coarse-grained multithreading switches between threads only when one thread
blocks, say on a memory read. Context switching is similar to process switching, with
considerable overhead.
2. Fine-grained multithreading occurs on smaller regular intervals, say on the boundary
of instruction cycles. However the architecture is designed to support thread
switching, so the overhead is relatively minor.
Note that for a multi-threaded multi-core system, there are two levels of scheduling, at the
kernel level:
The OS schedules which kernel thread(s) to assign to which logical processors, and when to make
context switches using algorithms as described above.
On a lower level, the hardware schedules logical processors on each physical core using some
other algorithm.
The UltraSPARC T1 uses a simple round-robin method to schedule the 4 logical processors (
kernel threads ) on each physical core.
The Intel Itanium is a dual-core chip which uses a 7-level priority scheme ( urgency ) to
determine which thread to schedule when one of 5 different events occurs.