2.1. Process Description: Chapter Two Process Management
2.1. Process Description: Chapter Two Process Management
2.1. Process Description: Chapter Two Process Management
CHAPTER TWO
2. PROCESS MANAGEMENT
2.1. Process description
Now consider a user PC. When the system is booted, many processes are secretly started, often
unknown to the user. For example, a process may be started up to wait for incoming email.
Another process may run on behalf of the antivirus program to check periodically if any new
virus definitions are available. In addition, explicit user processes may be running, printing files
and backing up the user’s photos on a USB stick, all while the user is surfing the Web. All this
activity has to be managed, and a multiprogramming system supporting multiple processes
comes in very handy here.
Modern computers work in a multitasking environment in which they execute multiple programs
simultaneously. These programs cooperate with each other and share the same resource, such as
memory and CPU. An operating system manages all processes to facilitate proper utilization of
these resources.
Important concept: decomposition. Given hard problem, chop it up into several simpler problems
that can be solved separately. A big size program should be broken down into processes to be
executed.
What is a process?
A process is just an instance of an executing program, including the current values of the
program counter, registers, and variables. Conceptually, each process has its own virtual CPU. In
reality, of course, the real CPU switches back and forth from process to process, but to
understand the system, it is much easier to think about a collection of processes running in
(pseudo) parallel than to try to keep track of how the CPU switches from program to program.
This rapid switching back and forth is called multiprogramming.
A process will need resources like CPU time, memory, files and I/O devices-to accomplish its
task. Resources are allocated to process either when it is created or while it is executing
The difference between a process and a program is subtle, but absolutely crucial. An analogy
may help you here. Consider a culinary-minded computer scientist who is baking a birthday cake
for his young daughter. He has a birthday cake recipe and a kitchen well stocked with all the
input: flour, eggs, sugar, extract of vanilla, and so on. In this analogy, the recipe is the program,
that is, an algorithm expressed in some suitable notation, the computer scientist is the processor
(CPU), and the cake ingredients are the input data. The process is the activity consisting of our
baker reading the recipe, fetching the ingredients, and baking the cake.
Now imagine that the computer scientist’s son comes running in screaming his head off, saying
that he has been stung by a bee. The computer scientist records where he was in the recipe (the
state of the current process is saved), gets out a first aid book, and begins following the
directions in it. Here we see the processor being switched from one process (baking) to a higher-
priority process (administering medical care), each having a different program (recipe versus
first aid book). When the bee sting has been taken care of, the computer scientist goes back to his
cake, continuing at the point where he left off.
The key idea here is that a process is an activity of some kind. It has a program, input, output,
and a state. A single processor may be shared among several processes, with some scheduling
algorithm being accustomed to determine when to stop work on one process and service a
different one. In contrast, a program is something that may be stored on disk, not doing anything.
A program is a passive entity, such as a file containing a list of instructions stored on disk (often
called an executable file), whereas a process is an active entity, with a program counter
specifying the next instruction to execute and a set of associated resources. A program becomes a
process when an executable file is loaded into memory.
System initialization
When an operating system is booted, typically numerous processes are created. Some of these
are foreground processes, that is, processes that interact with (human) users and perform work
for them. Others run in the background and are not associated with particular users, but instead
have some specific function.
Execution of a process-creation system call by a running process
Often a running process will issue system calls (e.g. fork ( ) or CreateProcess ( )) to create one
or more new processes to help it do its job. Creating new processes is particularly useful when
the work to be done can easily be formulated in terms of several related, but otherwise
independent interacting processes.
When the OS creates a process at the explicit request of another process, the action is referred to
as process spawning. When one process spawns another, the former is referred to as the parent
process, and the spawned process is referred to as the child process. Typically, the “related”
processes need to communicate and cooperate with each other.
Forking: want to make a copy of existing process (e.g., UNIX uses fork ( ) function).
Make sure process to be copied is not running and has all state saved.
Make a copy of code, data, and stack.
Copy PCB of source into new process.
Make process known to dispatcher/scheduler.
process has not yet been loaded into main memory, although its process control block has
been created.
Ready State: The new process that is waiting to be assigned to the processor. Or, a
process that is prepared to execute when given the opportunity.
Running State: A process is said to be running if it actually using the CPU at that
particular instant, the process that is currently being executed.
Blocked (or waiting) State: A process that cannot execute until some event occurs, such
as the completion of an I/O operation.
Terminated (or exit) State: A process that has been released from the pool of executable
processes by the OS, either because it halted or because it is aborted for some reason.
The transition among these five states is shown in the following diagram.
Null New: A new process is created to execute a program. This event occurs for any of
the reasons stated under process creation above.
New Ready: The OS will move a process from the New state to the Ready state when it is
prepared to take on an additional process. Most systems set some limit based on the number
of existing processes or the amount of virtual memory committed to existing processes. This
limit assures that there are not so many active processes as to degrade performance.
Ready Running: When it is time to select a process to run, the OS chooses one of the
processes in the Ready state. This is the job of the scheduler or dispatcher.
Running Exit: The currently running process is terminated by the OS if the process
indicates that it has completed, or if it aborts (see also situations for process termination
above).
Running Ready: The most common reason for this transition is that the running process
has reached the maximum allowable time for uninterrupted execution; virtually all
multiprogramming operating systems impose this type of time discipline. There are several
other alternative causes for this transition, which are not implemented in all operating
systems. Of particular importance is the case in which the OS assigns different levels of
priority to different processes. Suppose, for example, that process A is running at a given
priority level, and process B, at a higher priority level, is blocked. If the OS learns that the
event upon which process B has been waiting has occurred, moving B to a ready state, then it
can interrupt process A and dispatch process B. We say that the OS has preempted process A.
Finally, a process may voluntarily release control of the processor.
Running Blocked: A process is put in the blocked state if it requests something for which
it must wait. A request to the OS is usually in the form of a system service call; that is, a call
from the running program to a procedure that is part of the operating system code. For
example, a process may request a service from the OS that the OS is not prepared to perform
immediately. It can request a resource, such as a file or a shared section of virtual memory
that is not immediately available. Or the process may initiate an action, such as an I/O
operation, that must be completed before the process can continue. When processes
communicate with each other, a process may be blocked when it is waiting for another
process to provide data or waiting for a message from another process.
Blocked Ready: A process in the Blocked state is moved to the Ready state when the
event for which it has been waiting occurs.
o Ready Exit: For clarity, this transition is not shown on the state transition diagram.
In some systems, a parent may terminate a child’ process at any time. Also, if a parent
terminates, all child processes associated with that parent may be terminated.
o Blocked Exit: The comments under the preceding item apply.
The PCB contains important information about the specific process including:
The current state of the process i.e., whether it is ready, running, waiting, or whatever.
Unique identification of the process in order to track "which is which" information.
A pointer to parent process.
Similarly, a pointer to child process (if it exists).
The priority of process, priority level relative to other processes.
I/O status information. This information includes the list of I/O devices allocated to the
process, a list of open files, and so on.
Accounting information. This information includes the amount of CPU and real time
used, time limits, account numbers, job or process numbers, and so on.
Program counter i.e. the address of the next instruction in the program to be executed.
Memory pointers: Includes pointers to the program code and data associated with this
process, plus any memory blocks shared with other processes.
Context data: These are data that are present in registers in the processor while the
process is executing.
The PCB is a certain store that allows the operating systems to locate key information about a
process. Thus, the PCB is the data structure that defines a process to the operating systems.
Most modern computer systems allow more than one process to be executed simultaneously.
This is called Multitasking systems.
Context switching means switching the CPU to different processes. It is also done when a
process is switched from running state to blocked (ready) state. It requires saving of the state of
the current process into the PCB and load the saved PCB of the previous or new process.
A context switch is a mechanism to store and restore the state or context of a CPU in Process
Control block so that a process execution can be resumed from the same point at a later time.
Using this technique a context switcher enables multiple processes to share a single
CPU. Context switching is an essential part of a multitasking operating system features.
Dispatcher (also called Short Term Scheduler): inner-most portion of the OS that runs processes
without interference: Scheduler supports and facilitates the following activities
Run process for a while
Save its state
Load state of another process
Run the new process and after some time it reload the suspended /previous process.
In a single-processor system, only one process can run at a time; any others must wait until the
CPU is free and can be rescheduled. The objective of multiprogramming is to have some process
running at all times, in order to maximize CPU utilization. The idea is relatively simple. A
process is executed until it must wait, typically for the completion of some I/O request. In a
simple computer system, the CPU then just sits idle. All this waiting time is wasted; no useful
work is accomplished. With multiprogramming, we try to use this time productively. Several
processes are kept in memory at one time. When one process has to wait, the operating system
takes the CPU away from that process and gives the CPU to another process. This pattern
continues. Every time one process has to wait, another process can take over use of the CPU.
When more than one process is running, the operating system must decide which one should first
run. The part of the operating system concerned with this decision is called the scheduler, and
algorithm it uses is called the scheduling algorithm. The scheduler decides which process should
run when and for how long.
In multitasking and uniprocessor system scheduling is needed because more than one process is
in ready and waiting state. A certain scheduling algorithm is used to get all the processes to run
correctly. The processes should be in such a manner that no processes must be made to wait for a
long time.
Nearly all processes alternate between computing (or execution) and I/O request. A CPU
executes/runs for a while without stopping then an I/O may be made. When the I/O request
completes, the CPU resumes completing until the next I/O request occurs.
E.g. processes related to word processing soft wares editors, internet, and multimedia
applications.
Notes:
- The time needed for I/O operation for both CPU bound and I/O bound processes is
nearly the same. However, they are different in the frequency of I/O requests and
execution time.
- I/O bound process needed response time.
How do a process be classified as CPU bound or I/O bound? I/O bound and CPU bound are
theoretical and impossible to dictate which is what. But, by observing the history of I/O request,
it can be identified as I/O bound or CPU bound process.
When to schedule
A key issue related to scheduling is when to make scheduling decisions. It turns out that there are
a variety of situations in which scheduling is needed. First, when a new process is created, a
decision needs to be made whether to run the parent process or the child process. Since both
processes are in ready state, it is a normal scheduling decision and can go either way, that is, the
scheduler can legitimately choose to run either the parent or the child next.
Second, a scheduling decision must be made when a process exits. That process can no longer
run (since it no longer exists), so some other process must be chosen from the set of ready
processes. If no process is ready, a system-supplied idle process is normally run.
Third, when a process blocks on I/O or for some other reason, another process has to be selected
to run. Sometimes the reason for blocking may play a role in the choice.
Fourth, when an I/O interrupt occurs, a scheduling decision may be made. If the interrupt came
from an I/O device that has now completed its work, some process that was blocked waiting for
the I/O may now be ready to run. It is up to the scheduler to decide whether to run the newly
ready process, the process that was running at the time of the interrupt, or some third process.
A non-preemptive scheduling algorithm picks a process to run and then just lets it run until it
blocks (either on I/O or waiting for another process) or voluntarily releases the CPU. Even if it
runs for many hours, it will not be forcibly suspended. In effect, no scheduling decisions are
made during clock interrupts. After clock-interrupt processing has been finished, the process that
was running before the interrupt is resumed, unless a higher-priority process was waiting for a
now-satisfied timeout.
A scheduling discipline is non preemptive if once a process has been given the CPU, the CPU
cannot be taken away from that process until the assigned process completes its execution.
In contrast, a preemptive scheduling algorithm picks a process and lets it run for a maximum of
some fixed time. If it is still running at the end of the time interval, it is suspended and the
scheduler picks another process to run (if one is available). Doing preemptive scheduling
requires having a clock interrupt occur at the end of the time interval to give control of the CPU
back to the scheduler. If no clock is available, non-preemptive scheduling is the only option.
Scheduling decisions will be made at the end of each time interval.
Fairness:
Fairness is important under all circumstances. A scheduler makes sure that each process gets its
fair share of the CPU and no process can suffer indefinite postponement/delay. Not giving
equivalent or equal time is not fair.
Throughput:
If the CPU is busy executing processes, then work is being done. One measure of work is the
number of processes that are completed per time unit, called throughput. It is the number of jobs
per hour that the system completes. All things considered, finishing 50 jobs per hour is better
than finishing 40 jobs per hour. Hence, a scheduler should maximize the number of jobs
processed per unit time.
Turnaround:
Turnaround time is the statistically average time from the moment that a batch job is submitted
until the moment it is completed. It measures how long the average user has to wait for the
output. From the point of view of a particular process, the important criterion is how long it takes
to execute that process. The interval from the time of submission of a process to the time of
completion is the turnaround time. Turnaround time is the sum of the periods spent waiting to get
into memory, waiting in the ready queue, executing on the CPU, and doing I/O. Here the rule is:
Small is Beautiful.
Waiting time:
The CPU scheduling algorithm does not affect the amount of time during which a process
executes or does I/O; it affects only the amount of time that a process spends waiting in the ready
queue. Waiting time is the sum of the periods spent waiting in the ready queue.
Response Time:
In an interactive system, turnaround time may not be the best criterion. Often, a process can
produce some output fairly early and can continue computing new results while previous results
are being output to the user. Thus, another measure is the time from the submission of a request
until the first response is produced. This measure, called response time, is the time it takes to
start responding, not the time it takes to output the response. It is the time between issuing a
command and getting the result. A scheduler should minimize the response time for interactive
user.
CPU scheduling deals with the problem of deciding which of the processes in the ready queue is
to be allocated the CPU. There are many different CPU-scheduling algorithms. In this section,
we describe several of them.
FCFS scheme is not useful in scheduling interactive users because it cannot guarantee good
response time. One of the major drawbacks of this scheme is that the average time is often quite
long.
Example:
Consider the following set of processes that arrive at time 0, with the length of the CPU burst
time (it is the amount of time required by a process or can be said the amount of time required by
the process to finish) given in milliseconds:
If the processes arrive in the order P1, P2, P3, and are served in FCFS order, we get the result
shown in the following Gantt chart, which is a bar chart that illustrates a particular schedule,
including the start and finish times of each of the participating processes:
The waiting time is 0 milliseconds for process P1, 24 milliseconds for process P2, and 27
milliseconds for process P3. Thus, the average waiting time is (0+ 24 + 27)/3 = 17 milliseconds.
If the processes arrive in the order P2, P3, P1, however, the results will be as shown in the
following Gantt chart:
The average waiting time is now (6 + 0 + 3)/3 = 3 milliseconds. This reduction is substantial.
Thus, the average waiting time under an FCFS policy is generally not minimal and may vary
substantially if the processes CPU burst times vary greatly.
The SJF algorithm favors for short jobs (or processes) at the expense of longer ones. Since the
SJF scheduling algorithm gives the minimum average time for a given set of processes, it is
probably optimal.
Example:
Consider the following set of processes, with the length of the CPU burst given in milliseconds:
Using SJF scheduling, we would schedule these processes according to the following Gantt
chart:
The waiting time is 3 milliseconds for process P1, 16 milliseconds for process P2, 9 milliseconds
for process P3, and 0 milliseconds for process P4. Thus, the average waiting time is
(3+16+9+0)/4=7 milliseconds. By comparison, if we were using the FCFS scheduling scheme,
the average waiting time would be 10.25 milliseconds.
The SJF scheduling algorithm is provably optimal, in that it gives the minimum average waiting
time for a given set of processes. Moving a short process before a long one decreases the waiting
time of the short process more than it increases the waiting time of the long process.
Consequently, the average waiting time decreases.
If a new process arrives with a shorter next CPU time than what is left of the currently executing
process, then the new process get the CPU.
The SRT is the preemptive counterpart of SJF and useful in time-sharing environment.
In SRT scheduling, the process with the smallest estimated left run-time to completion is
run next, including new arrivals.
In SJF scheme, once a job begins executing, it run to completion.
In SRT scheme, a running process may be preempted/ interrupted by a new arrival
process with shortest estimated remaining/left run-time.
The algorithm SRT has higher overhead than its counterpart SJF.
The SRT must keep track of the elapsed time of the running process and must handle
occasional preemptions.
In this scheme, arrival of small processes will run almost immediately. However, longer
jobs have even longer mean waiting time.
Example:
As an example, consider the following four processes, with the length of the CPU burst given in
milliseconds:
If the processes arrive at the ready queue at the times shown and need the indicated burst times,
then the resulting preemptive SJF schedule is as depicted in the following Gantt chart:
Process P1 is started at time 0, since it is the only process in the queue. Process P2 arrives at time
1. The remaining time for process P1 (7 milliseconds) is larger than the time required by process
P2 (4 milliseconds), so process P1 is preempted, and process P2 is scheduled. The average waiting
time for this example is [(10−1) + (1−1) + (17−2) + (5−3)]/4 = 26/4 = 6.5 milliseconds. Non-
preemptive SJF scheduling would result in an average waiting time of 7.5 milliseconds.
One of the simplest, fairest and most widely used algorithms is round robin (RR).
In the round robin scheduling, processes are dispatched in a FIFO manner but are given a limited
amount of CPU time called a time-slice or a quantum time. If a process does not complete before
its CPU-time expires, the CPU is preempted/interrupted and given to the next process waiting in
a queue. The preempted process is then placed at the back of the ready list. Round Robin
Scheduling is preemptive (at the end of time-slice) therefore it is effective in time-sharing
environments in which the system needs to guarantee reasonable response times for interactive
users.
The only interesting issue with round robin scheme is the length of the quantum. Setting the
quantum too short causes too many context switches and lower the CPU efficiency. On the other
hand, setting the quantum too long may cause poor response time and approximates FCFS. So
the slice time should not be too short and too long.
Example:
Consider the following set of processes that arrive at time 0, with the length of the CPU burst
given in milliseconds:
If we use a time quantum of 4 milliseconds, then process P1 gets the first 4 milliseconds. Since it
requires another 20 milliseconds, it is preempted after the first time quantum, and the CPU is
given to the next process in the queue, process P2. Process P2 does not need 4 milliseconds, so it
quits before its time quantum expires. The CPU is then given to the next process, process
P3.Once each process has received 1 time quantum, the CPU is returned to process P 1 for an
additional time quantum. The resulting RR schedule is as follows:
Let’s calculate the average waiting time for the above schedule. P1 waits for 6 milliseconds (10 -
4), P2 waits for 4 milliseconds, and P3 waits for 7 milliseconds. Thus, the average waiting time is
17/3 = 5.66 milliseconds.
In the RR scheduling algorithm, no process is allocated the CPU for more than 1 time quantum
in a row (unless it is the only runnable process). If a process’s CPU burst exceeds 1 time
quantum, that process is preempted and is put back in the ready queue. The RR scheduling
algorithm is thus preemptive.
SJF algorithm is also a priority algorithm where the priority is the inverse of the (predicted) next
CPU burst. That is, the longer the CPU burst, the lower the priority and vice versa.
Note that we discuss scheduling in terms of high priority and low priority. Priorities are generally
indicated by some fixed range of numbers. However, there is no general agreement on whether 0
is the highest or lowest priority. Some systems use low numbers to represent low priority; others
use low numbers for high priority. This difference can lead to confusion. In this text, we assume
that low numbers represent high priority.
Example:
Consider the following set of processes, assumed to have arrived at time 0 in the order P1, P2, ···,
P5, with the length of the CPU burst given in milliseconds:
Using priority scheduling, we would schedule these processes according to the following Gantt
chart:
2.8. Threads
In traditional operating systems, each process has an address space and a single thread of control.
In fact, that is almost the definition of a process. Nevertheless, there are frequently situations in
which it is desirable to have, multiple threads of control in the same address space running in
quasi-parallel, as though they were(almost) separate processes (except for die shared address
space).
A thread is a basic unit of CPU utilization; it comprises a thread ID, a program counter, a register
set, and a stack. It shares with other threads belonging to the same process its code section, data
section, and other operating-system resources, such as open files and signals. A traditional (or
heavy weight) process has a single thread of control. If a process has multiple threads of control,
it can perform more than one task at a time.
Process: A collection of one or more threads and associated system resources (such as memory
containing both code and data, open files, and devices). This corresponds closely to the concept
of a program in execution. By breaking a single application into multiple threads, the
programmer has great control over the modularity of the application and the timing of
application-related events.
In a multithreaded environment, a process is defined as the unit of resource allocation and a unit
of protection. The following are associated with processes:
Thread: A dispatchable unit of work. It includes a processor context (which includes the
program counter and stack pointer) and its own data area for a stack (to enable subroutine
branching). A thread executes sequentially and is interruptable so that the processor can turn to
another thread.
Within a process, there may be one or more threads, each with the following:
A thread execution state (Running, Ready, etc.).
A saved thread context when not running; one way to view a thread is as an
independent program counter operating within a process.
An execution stack.
Some per-thread static storage for local variables.
Access to the memory and resources of its process, shared with all other threads
in that process.
Generally speaking,
- Threads are not independent as processes. All threads within a process have exactly the
same address space.
- It is not possible to protect between threads because they need to cooperate. But process
should be capable of protecting one another.
- Process can be hostile to each other.
Advantages of threads
Why would anyone want to have a kind of process with in a process? It turns out there are
several reasons for having these mini-processes, called threads (they are light weight process).
Let us now examine some of them. The main reason for having threads is that in many
applications, multiple activities are going on at once. Some of these may block from time to
time. By decomposing such an application into multiple sequential threads that run in quasi-
parallel, the programming model becomes simpler.
- Efficiency: decomposing big task into sub tasks & doing sub tasks concurrently is efficient.
- Context switching cost is minimize for threads, because threads are light weight processes.
- Resource consumption is minimum, because threads share resources of a process.