Understanding Processes and Threads in OS
Understanding Processes and Threads in OS
1
Processes
The Process Model
System Initialization:
• When OS is booted, several processes are created.
• There may be foreground processes and background processes.
• Foreground processes interact with user and work for them.
• Background processes are not associated with particular users, but
have some specific function. e.g. process to accept incoming mail,
to accept incoming request for web pages etc.
• Processes that stay in the background to handle some activity such
as email, web pages, news, printing etc. are called daemons.
3
Execution of a process creation system:
• a running process issue system calls to create one or more new
processes to help it to do its job.
Normal exit:
• Process terminates when they have done their work.
• After compilation gets over, compiler executes system call to tell
OS that it is finished. This call is exit in UNIX.
Error exit:
• Process terminates when it finds a fatal error.
• For ex., trying to compile a program which does not exists.
6
Fatal error:
• Process terminates because of an error caused by itself, often due to
program bug.
• For ex, executing illegal instruction, referencing non existent memory,
divide by zero etc.
• In UNIX, it is possible to handle certain errors, where process is
signaled instead of termination.
8
Process States
9
• Four transitions are possible among these three states:
1. Transition 1 occurs when a process discovers that it can not
continue. It happens when some input is required which is not
available.
2. Transition 2 occurs when the scheduler decides that the running
process has run long enough, and it is time to let another process
have some CPU time.
3. Transition 3 occurs when all other processes have had their fair
share and it is time for the first process to get the CPU to run again.
4. Transition 4 occurs when the external event for which a process was
waiting ( such as the arrival of some input) happens. If no other
process is running at that instant, transition 3 will be triggered and
the process will start running. Otherwise, it may have to wait in
ready state for a little while until the CPU is available and its turn
comes.
Implementation of Processes
• OS maintains a table called process table, with one entry per process.
• These entries are also known as Process Control Blocks.
• Each entry contains information about
– Process’ state
– Program counter
– Stack pointer
– Memory allocation
– Status of its open files
– Accounting and scheduling information
– Everything else which must be saved when process is switched form one
state to other so that it can be restarted later as if it had never been
stopped.
Fields of a process table entry
12
What OS does when interrupt occurs
• Associated with each I/O device class is a location called interrupt vector.
• It contains the address of interrupt service procedure.
• When any interrupt occurs, user process’ PC, PSW and possibly one or more
registers are pushed onto the stack by interrupt hardware.
• The computer then jumps to the address specified in the interrupt vector. That
is all hardware does.
• Now it is the task of interrupt service procedure.
• It starts working by saving registers, often in process table entry for the
current process.
• Then the information pushed onto the stack by the interrupt is removed and
the stack pointer is set to point to a temporary stack used by the process
handler.
• When this routine is finished, it calls a C procedure to do the rest of the work
for this specific interrupt type.
• When it has done its job, possibly making some process now ready, the
scheduler is called to see who to run next.
• After that, control is passed back to the assembly language code to load up the
registers and memory map for now-current process and start it running.
13
Skeleton of what lowest level of OS does when an
interrupt occurs
14
Threads
• In traditional OS, each process has an address space and a single
thread of control.
• 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 separate processes.
Thread Model:
• The process model is based on two independent concepts: resource
grouping and execution.
• Resource grouping: Process is a way to group related resources
together. A process has an address space containing program text, data,
open files, child processes, pending alarms, signal handlers,
accounting information etc.
• Execution: Other concept a process has is a thread of execution,
usually shortened to thread.
15
• The thread has
– A program counter that keeps track of which instruction to execute
next.
– Registers which hold its current working variables.
– Stack which contains the execution history, with one frame for
each procedure called but not yet returned from.
• Processes are used to group resources together, threads are the entities
scheduled for execution on the CPU.
• Having multiple threads running in parallel in one process is
analogous to having multiple processes running in parallel in one
computer. In the former case, the threads share an address space, open
files and other resources. In the latter case, processes share physical
memory, disks, printers and other resources.
• As threads are having some of the properties of processes, they are
sometimes called lightweight processes.
16
Threads
The Thread Model
18
• Like a traditional process ( a process with only one thread), a thread can
be in any one of several states: running, blocked, ready or terminated.
• A running thread currently has CPU and is active.
• A blocked thread is waiting for some event to unblock it.
• A ready thread is scheduled to run and will as soon as its turn comes up.
• The transitions between thread states are same as those between process
states.
19
Why thread needs its own stack?
• Each thread’s stack contains one frame for each procedure called but
not yet returned from. This frame contains the procedure’s local
variables and the return address to use when procedure call has
finished.
• Each thread will generally call different procedures and thus a
different execution history. This is why is thread needs its own stack.
20
• When multithreading is present, processes normally start with a single
thread present.
• This thread has the ability to create new threads by calling a library
procedure called thread_create.
– New thread automatically runs in the address space of the creating thread.
• When a thread has finished its work, it can exit by calling a library
procedure called thread_exit.
• In some systems, one thread can wait for a specific thread to exit by
calling a procedure thread_wait.
• Another thread call is thread_yield, which allows a thread to
voluntarily give up the CPU to let another thread run.
– This call is important because there is no clock interrupt to actually
enforce timesharing like process. Thus it is important for threads to be
polite and voluntarily surrender CPU from time to time to give other
threads a chance to run.
Questions imposed by multithreaded system
• If the parent process has multiple threads, should the child also have
them? If not, the process may not function properly, since all of them
may be essential.
• If the child process gets as many threads as parent, what happens if a
thread in parent was blocked on a read call, say, from keyboard? Are
two threads now blocked on keyboard, one in parent and one in child?
When a line is typed, do both threads get a copy of it? Only parent?
Only child?
• Thread shares many data structures. What happens if one thread closes
a file while another one is still reading from it?
• Suppose that one thread notices that there is too little memory and
starts allocating more memory. Part way through, thread switch occurs
and new thread also notices that there is too little memory and starts
allocating more memory. Memory will probably be allocated twice.
Thread Usage
• Four reasons for having threads in system:
1. 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.
2. Threads do not have any resources attached to them, they are easier
to create and destroy than processes.
3. Threads yield no performance gain when all of them are CPU
bound, but when there is substantial computing and also substantial
I/O, having threads allows these activities to overlap, thus speeding
up the application.
4. Threads are useful on systems with multiple CPUs, where read
parallelism is possible.
Thread Usage Example
24
Thread Usage Example
33
Scheduler Activations
• Goal – mimic functionality of kernel threads
– gain performance and flexibility of user space threads
• Avoids unnecessary user/kernel transitions
• Kernel assigns virtual processors to each process
– lets runtime system allocate threads to processors
• Problem:
Fundamental reliance on kernel (lower layer)
calling procedures in user space (higher layer)
34
Pop-Up Threads
36
Making Single-Threaded Code Multithreaded (2)
Where two or more processes are reading or writing some shared data and the final
result depends on who runs precisely when are called race conditions.
39
Critical Regions
• To avoid race conditions, we require mutual exclusion, that is, some way of
making sure that if one process is using a shared variable or file, the other
processes will be excluded from doing the same thing.
• The part of the program where the share memory is accessed is called the critical
region or critical section.
• If we could arrange matters such that no two processes were ever in their critical
regions at the same time, we could avoid races.
– When process finishes with critical region, calls leave_region and sets
lock to 0
• enter_region:
TSL REGISTER, LOCK
CMP REGISTER,#0
JNE enter_region
RET
• Leave_region:
MOVE LOCK,#0
RET
Sleep and Wakeup
• Problems with peterson’s solution and TSL instruction:
– Require busy waiting – hence waste CPU time
– Priority Inversion Problem:
• Consider a computer with two processes, H with high priority and L
with low priority.
• The scheduling rules are such that H is run whenever it is in ready
state.
• At a certain moment, with L in its critical region, H becomes ready to
run.
• H now begins busy waiting but since L is never scheduled while H is
running, L never gets chance to leave its critical region, so H loops
foreever.
– Solution:
• Wakeup waiting bit is to be added.
• When a wakeup is sent to a process that is still awake, this bit is set.
• Later, when process tries to go to sleep, if the wakeup waiting bit is
on, it will be turned off, but the process stay awake.
• The wakeup waiting bit is piggy bank for wakeup signals.
Semaphores
• It is a variable to count the no of wakeups saved for future use.
• A semaphore could have the value 0, indicating that no wakeups were saved,
or some positive value if one or more wakeups were pending.
• Two operations : Down & Up
• Down operation on a semaphore checks to see if the value is greater than 0. If
so, it decrements the value (uses one stored wakeup) and just continues. If the
value is 0, the process is put to sleep without completing down for the
moment.
• Checking the value, changing it and possibly going to sleep is (indivisible)
atomic action.
– It is guaranteed that once a semaphore operation has started, no other
process can access the semaphore until the operation has completed.
• The up operation increments the value of the semaphore addressed.
– If one or more processes were sleeping on that semaphore, unable to
complete an earlier down operation, one of them is chosen by the system
and is allowed to complete its down.
– Thus, after an up on a semaphore with processes sleeping on it, the
semaphore will still be 0, but there will be one fewer process sleeping on
it.
The producer-consumer problem using semaphores
• Three semaphores are used:
– full: count the number of slots that are full, initially 0.
– empty: count the number of slots that are empty, initially equal to number
of slots in the buffer.
– mutex: take care the producer and consumer do not access the buffer at
the same time, initially 1.
• full and empty semaphores are used for synchronization and mutex
semaphore is used for mutual exclusion.
Mutexes
• It is used when semaphore’s ability to count is not needed.
• Mutexes are good only for managing mutual exclusion to some shared
resource or piece of code.
• They are useful in thread packages that are implemented entirely in
user space.
• Mutex is a variable that can be in one of two states: unlocked or
locked. 0 means unlocked and all other values meaning locked.
• Two procedures are used with mutexes.
– When a thread (or process) needs access to a critical region, it calls
mutex_lock. If the mutex is current unlocked, the call succeeds and the
calling thread is free to enter the critical region.
– If mutex is already locked, the calling thread is blocked until the thread in
the critical region is finished and calls mutex_unlock.
• As mutexes are simple, they can easily be implemented in user space
if a TSL instruction is available.
Implementation of mutex_lock and mutex_unlock
• Difference between call to mutex_lock and enter_region:
– When enter_region fails to enter the critical region, it does busy waiting.
– Eventually clock interrupt switches cpu to other process, which may release
lock.
– With threads, as no clock interrupt is available, thread that tries to acquire a
lock by busy waiting will loop forever and never acquire the lock because it
never allows any other thread to run and release the lock.
– In mutex_lock, when thread fails to acquire a lock, it calls thread_yield to give
up CPU to another thread.
– No busy waiting. When thread runs next time, it tests the lock again.
– As thread_yield is just a call to thread scheduler in user space, it is very fast.
– Not required for kernel involvement.
• If processes have disjoint address spaces, how can they share turn variable in
peterson’s algorithm, or semaphores or a common buffer? Answer is:
– Some of the shared data structures, such as the semaphores, can be stored in
the kernel and only accessed via system calls.
– Most OS offer a way for processes to share some portion of their address space
with other processes.
– In nothing else is possible, a shared file can be used.
Monitors
• Problem with semaphores:
– Suppose that two down’s in the producer’s code were reversed in order, so
mutex was decremented before empty instead of after it. If the buffer were
completely full, the producer would block, with mutex set to 0. consequently,
next time when consumer tried to access the buffer, it would do a down on
mutex, now 0, and block too. Both processes would stay blocked forever.
– Care must be taken while using semaphores.
• Monitor is a higher-level synchronization primitive.
• It is a collection of procedures, variables, and data structures that are all grouped
together in a special kind of module or package.
• Processes may call the procedures in a monitor whenever they want to, but they
cannot directly access the monitor’s internal data structures from procedures
declared outside the monitor.
• It have an important property that only one process can be active in a monitor at
any instant.
• It is a programming language construct, so compiler will handle it accordingly.
• As the compiler is arranging for mutual exclusion, it is much less likely that
something will go wrong.
• It is sufficient to know that by turning all the critical regions into monitor
procedures, no two processes will ever execute their critical region at the same
time.
Monitors
Example of a monitor
60
• Along with mutual exclusion, a way for processes to block is also needed when
they cannot proceed.
• We can have two condition variables full and empty along with two operations on
them, wait and signal.
• When a monitor procedure discovers that it cannot continue because of full buffer,
it does a wait on variable full. This action causes the calling process to block. It
also allows another process that had been previously prohibited from entering the
monitor to enter now.
• This other process, the consumer, can wake up its sleeping partner by doing a
signal on the condition variable that its partner is waiting on.
• A process doing a signal must exit the monitor immediately to allow another
process to get scheduled.
• Sleep and wakeup failed because while one process was trying to go to sleep, the
other one was trying to wake it up. With monitors, this cannot happen. The
automatic mutual exclusion on monitor procedures guarantees that processes will
be able to finish wait/signal before other process enters monitor.
• Problems with monitors:
– It is a programming language construct. The compiler must recognize them
and arrange for mutual exclusion somehow.
– Monitors and semaphores are designed for solving mutual exclusion problem
on one or more CPUs that all have access to a common memory. In a
distributed system consisting of multiple CPUs, each with its own private
memory, connected by a LAN, these primitives become inapplicable.
• Conclusion:
– Semaphores are too low level and monitors are not usable except in a few
programming languages. Also, none of the primitives provide for information
exchange between machines.
Message Passing
• This method of inter process communication uses two primitives, send and receive.
• They are system calls and can be available as library procedures.
• Design issues for message passing systems:
– Acknowledgement message is to be sent back to sender to guard against lost
messages. If the sender does not receive acknowledgement message within a
time interval, it retransmit the message.
– If message itself it received correctly but acknowledgement is lost. It is
essential to distinguish a new message from retransmitted one. It can be solved
by putting consecutive sequence no in each original msg.
– Naming of processes
– Authentication
– performance
Message Passing
• Use of a barrier
– processes approaching a barrier
– all processes but one blocked at barrier
– last process arrives, all are let through
65
Scheduling
• The part of OS that makes the choice between processes which one should run next
is called Scheduler, and the algorithm it uses is called Scheduling Algorithm.
• Computer Bound processes are those who spend most of their time in computing,
using CPU.
– Have lond CPU bursts
– Infrequent I/O waits
• I/O Bound processes are those who spend most of their time waiting for I/O.
– Short CPU bursts
– Frequent I/O waits
• As CPUs are improved much faster than disks, If an I/O bound process wants to
run, it should get a chance quickly so it can issue its disk request and keep the disk
busy.
Scheduling
• When to schedule?
1. When a new process is created:
– A decision needs to be made whether to run the parent process or the child
process.
2. When a process exits:
– As process can no longer run, some other process must be chosen from the
set of ready processes.
3. When a process blocks on I/O, on a semaphore or for some other reason.
4. When an I/O interrupt occurs:
– If interrupt comes from an I/O device that has now finished its work, some
process that was blocked waiting for I/O may now be ready to run.
– It is up to Scheduler to decide to run newly ready process, process that was
running when interrupt arrived should continue running, or some third
process should run.
Scheduling
Two main categories with respect to how they deal with clock interrupt:
• Nonpreemptive:
– Pick a process to run until it blocks or until it voluntarily releases the CPU.
– CPU will not be forcefully taken back.
– No scheduling decision are made during clock interrupts.
• Preemptive:
– Picks a process and let it run for a max of some fixed time.
– Currently running process is suspended at every clock interrupt.
Three categories with respect to environment in which they work:
• Batch:
– No users are waiting for a quick response.
– Non preemptive algorithms or preemptive algorithm with long time periods
can be used.
• Interactive:
– Preemption is essential to keep one process from hogging CPU and denying
service to the others.
• Real time:
– Preemption is sometimes not needed because processes know that they may
no turn for long periods of time.
Scheduling Algorithm Goals
69
Scheduling in Batch Systems
• First Come First Served:
– It is non preemptive
– Processes are assigned the CPU in order they request it.
– A single queue of ready processes are maintained.
– When the running process blocks, the first process on the queue is run next. When a
blocked process becomes ready, like a newly arrived job, it is put on the end of the
queue.
• Advantages:
– Easy to understand
– Easy to program
– Giving fair chance to process. (one which is waiting since long, given first chance)
• Disadvantages:
– Non Preemption sometimes increase run time of process
• Shortest Job first:
– It assumes that run times of processes are known in advance.
– When several equally important jobs are sitting in the input queue waiting to be
started, the scheduler picks the shortest job first.
• Example:
– Four jobs A,B,C, and D with run times of 8,4,4 and 4 minutes.
– By running them in this order, turnaround time for A is 8 minutes, for B is 12
minutes, for C is 16 minutes and for D is 20 minutes, for an average of 14 minutes.
– Using shortest job first strategy, the turnaround times are now 4,8,12 and 20
minutes for an average of 11 minutes.
• Advantage:
– It is optimal. For example, consider four jobs with run times of a, b, c and d
respectively. First job finishes at time a, second finishes at time a+b, and so on.
– The mean turnaround time is (4a+3b+2c+d)/4.
– It is clear that a contributes more to average than other so it should be shrotest, with
b next, then c and finally d as the longest as it affects only its own turnaround time.
• Disadvantage:
– It is optimal only when all the jobs are available simultaneously.
• Shortest Remaining time Next:
– It is a preemptive version of shortest job first.
– It always chooses the process whose remaining run time is shortest.
– It also assumes that run times of processes are known in advance.
– When a new job arrives, its total time is compared to the current process’ remaining
time.
– If new job needs less time to finish than current process, the current process is
suspended and new job is started.
• Advantage:
– It allows new short jobs to get good service.
Three level scheduling
73
Scheduling in Interactive Systems
• Round Robin Scheduling:
– It is oldest, simplest, fairest and most widely used algorithm.
– Each process is assigned a time interval, called quantum.
– If the process is still running at the end of the quantum, the CPU is preempted and given to
another process.
– List of runnable processes is maintained. When the process uses up its quantum, it is put on the
end of the list as show below.
• Length of quantum:
– Suppose that context switch takes 1 ms and quantum is 4 ms. With this parameters, after doing 4
ms of useful work, CPU will have to spend 1 ms on process switching. 20% of CPU time will be
wasted on administrative overhead.
– To improve CPU efficiency, if quantum is set to 100 ms, wasted time will be 1%. But for
interactive system, it is not good to wait for 100 ms for every response.
– Conclusion: Setting quantum too short causes too many process switches and lowers the CPU
efficiency, and setting it too long cause poor performance for short interactive request. Hence,
quantum around 20-50 ms is often a reasonable compromise.
74
• Priority Scheduling:
– Each process is assigned a priority, and the runnable process with highest priority is
allowed to run.
– To prevent high-priority processes from running indefinitely, the scheduler may
decrease the priority of currently running process at each clock tick. If this action
causes its priority to drop below that of the next highest process, a process switch
occurs.
– Alternatively, each process may be assigned a maximum time quantum that it is
allowed to run. When this quantum is used up, the next highest priority process is
given a chance to run.
– Priorities can be assigned to processes statically or dynamically.
– A simple algorithm for giving good service to I/O bound processes is to set the
priority to 1/f, where f is the fraction of last quantum that a process used. A process
that used only 1 ms of its 50 ms quantum would get priority 50, while a process that
ran 25 ms before blocking would get priority 2, and a process that used the whole
quantum would get priority 1.
– Group processes into priority classes and use priority scheduling among the classes
but round-robin within each class.
– The scheduling algorithm is as follows: as long as there are runnable processes in
priority class 4, run each one for one quantum, round robin fashion. If priority class
4 is empty, then run class 3 processes round robin and so on.
– If priorities are not adjusted occasionally, lower priority classes may all starve to
death.
• Multiple Queues:
– Set up process in priority classes.
– Processes in the highest class run for one quantum. Processes in next highest class
run for two quantum and so on.
– Whenever a process used up all the quantum allocated to it, it was moved down one
class.
– Consider a process that needed to compute continuously for 100 quantum. It would
initially be given one quantum, then swapped out. Next time it would get two
quantum and swapped out. On succeeding runs it would get 4,8,16,32 and 64
quantum, although it would have used only 37 of the final 64 quantum to complete
it s work. Only 7 swaps are needed instead of 100 with a pure round-robin
algorithm.
• Shortest Process Next:
– As shortest job first always produce minimum average response time for batch
system, it would be nice if it could be used for interactive processes as well.
– Interactive processes generally follow the pattern of wait for command, execute
command, wait for command, and so on.
– The only problem is figuring out which of the currently runnable processes is the
shorter one.
– One approach is to make estimates based on past behavior and run the process with
the shortest estimated running time.
– Suppose that estimated time per command for some terminal is T0, Next run is
measured to be T1. Estimate can be updated by taking a weighted sum of these two
numbers, that is aT0 + (1-a)T1. with a = ½,
T0, T0/2 + T1/2, T0/4 + T1/4 + T2/2, T0/8 + T1/8 + T2/4 + T3/2
– The technique of estimating the next value in series by taking the weighted average
of the current measured value and the previous estimate is sometimes called aging.
• Guaranteed Scheduling:
– Make real promises to the users about performance and then live up to them.
– The promise is: if there are n users logged in while a process is working, it will
receive about 1/n of the CPU power.
– To make good on this promise, the system must keep track of how much CPU
each process has had since its creation. It then computes the amount of CPU
each one is entitled to, namely the time since creation divided by n.
– Since the amount of CPU time each process has actually had is also known, it
is straightforward to compute the ratio of actual CPU time consumed to CPU
time entitled.
– A ratio of 0.5 means that a process has only had half of what is should have
had and a ratio of 2 means that a process has had twice as much as it was
entitled to.
– The algorithm is then to run the process with the lowest ratio until its ratio has
moved above its closet competitor.
• Disadvantage:
– It is difficult to implement
• Lottery Scheduling:
– Idea is to give processes lottery tickets for various system resources, such as
CPU time.
– Whenever scheduling decision has to be made, a lottery ticket is chosen at
random and the process holding that ticket gets the resource.
– When applied to CPU scheduling, the system might hold a lottery 50 times a
second, with each winner getting 20 ms of CPU time as a prize.
– More important processes can be given extra tickets, to increase their chance
of winning.
– If there are 100 tickets outstanding, and one process holds 20 of them, it will
have a 20 percent chance of winning each lottery.
– In contrast to Priority scheduler, where it is very hard to state what having a
priority of 40 actually means, here the rule is clear: a process holding a
fraction f of the tickets will get about a fraction f of the resource in question.
• Important properties:
– If a new process show up and is granted some tickets, at the very next lottery it
will have a chance of winning in proportion to the no of tickets it holds. i.e.
lottery scheduling is highly responsive.
– Cooperating processes may exchange tickets if they wish. For example, when
a client process send a message to a server process and then blocks, it may
give all of its tickets to the server, to increase the chance of the server running
next. When the server is finished, it returns the tickets so that client can run
again.
• Fair Share Scheduling:
– So far it is assumed that each process is scheduled on its own, without regard
to who its owner is.
– As a result, if user 1 starts up 9 processes and user 2 starts up 1 process, with
round robin or equal priorities, user 1 will get 90% of the CPU and user 2 will
get only 10% of it.
– To prevent this situation, owner of process is taken into account.
– Each user is allocated some fraction of the CPU and the scheduler picks
processes in such a way as to enforce it.
– Thus if two users have each been promised 50% of the CPU, they will each
get that, no matter how many processes they have in existence.
Scheduling in Real-Time Systems
• The events that a real time system may have to respond to is
categorized as
– Periodic events (occurring at regular intervals)
– Aperiodic (occurring unpredictably)
• A system may have to respond to multiple periodic events. Depending
on how much time each event requires for processing, it may not even
be possible to handle them all. For example, there are
– m periodic events
– event i occurs with period Pi and requires Ci seconds
– Then the load can only be handled if
m
Ci
i 1 Pi
1
81
Policy versus Mechanism
82
Thread Scheduling
83
Thread Scheduling
84