Unit 2-Exercises - Solutions

Download as pdf or txt
Download as pdf or txt
You are on page 1of 16

3

CHAPTER

Processes
Practice Exercises
3.1 Using the program shown in Figure 3.30, explain what the output will
be at Line A.
Answer:
The result is still 5 as the child updates its copy of value. When control
returns to the parent, its value remains at 5.
3.2 Including the initial parent process, how many processes are created by
the program shown in Figure 3.31?
Answer:
There are 8 processes created.
3.3 Original versions of Apple’s mobile iOS operating system provided no
means of concurrent processing. Discuss three major complications that
concurrent processing adds to an operating system.
Answer: FILL
3.4 The Sun UltraSPARC processor has multiple register sets. Describe what
happens when a context switch occurs if the new context is already
loaded into one of the register sets. What happens if the new context is
in memory rather than in a register set and all the register sets are in
use?
Answer:
The CPU current-register-set pointer is changed to point to the set
containing the new context, which takes very little time. If the context is
in memory, one of the contexts in a register set must be chosen and be
moved to memory, and the new context must be loaded from memory
into the set. This process takes a little more time than on systems with
one set of registers, depending on how a replacement victim is selected.
3.5 When a process creates a new process using the fork() operation, which
of the following state is shared between the parent process and the child
process?

a. Stack
9
10 Chapter 3 Processes

b. Heap
c. Shared memory segments
Answer:
Only the shared memory segments are shared between the parent
process and the newly forked child process. Copies of the stack and
the heap are made for the newly created process.
3.6 With respect to the RPC mechanism, consider the “exactly once” semantic.
Does the algorithm for implementing this semantic execute correctly
even if the ACK message back to the client is lost due to a network
problem? Describe the sequence of messages and discuss whether
“exactly once” is still preserved.
Answer:
The “exactly once” semantics ensure that a remore procedure will
be executed exactly once and only once. The general algorithm for
ensuring this combines an acknowledgment (ACK) scheme combined
with timestamps (or some other incremental counter that allows the
server to distinguish between duplicate messages).
The general strategy is for the client to send the RPC to the server
along with a timestamp. The client will also start a timeout clock. The
client will then wait for one of two occurrences: (1) it will receive an ACK
from the server indicating that the remote procedure was performed,
or (2) it will time out. If the client times out, it assumes the server was
unable to perform the remote procedure so the client invokes the RPC a
second time, sending a later timestamp. The client may not receive the
ACK for one of two reasons: (1) the original RPC was never received by
the server, or (2) the RPC was correctly received —and performed —by
the server but the ACK was lost. In situation (1), the use of ACKs allows
the server ultimately to receive and perform the RPC. In situation (2),
the server will receive a duplicate RPC and it will use the timestamp to
identify it as a duplicate so as not to perform the RPC a second time. It
is important to note that the server must send a second ACK back to the
client to inform the client the RPC has been performed.
3.7 Assume that a distributed system is susceptible to server failure.
What mechanisms would be required to guarantee the “exactly once”
semantics for execution of RPCs?
Answer:
The server should keep track in stable storage (such as a disk log)
information regarding what RPC operations were received, whether
they were successfully performed, and the results associated with the
operations. When a server crash takes place and a RPC message is
received, the server can check whether the RPC had been previously
performed and therefore guarantee “exactly once” semanctics for the
execution of RPCs.
6
CHAPTER

CPU Scheduling
Practice Exercises
6.1 A CPU-scheduling algorithm determines an order for the execution
of its scheduled processes. Given n processes to be scheduled on one
processor, how many different schedules are possible? Give a formula
in terms of n.
Answer:
n! (n factorial = n × n – 1 × n – 2 × ... × 2 × 1).
6.2 Explain the difference between preemptive and nonpreemptive schedul-
ing.
Answer:
Preemptive scheduling allows a process to be interrupted in the midst of
its execution, taking the CPU away and allocating it to another process.
Nonpreemptive scheduling ensures that a process relinquishes control
of the CPU only when it finishes with its current CPU burst.
6.3 Suppose that the following processes arrive for execution at the times
indicated. Each process will run for the amount of time listed. In
answering the questions, use nonpreemptive scheduling, and base all
decisions on the information you have at the time the decision must be
made.

Process Arrival Time Burst Time


P1 0.0 8
P2 0.4 4
P3 1.0 1

a. What is the average turnaround time for these processes with the
FCFS scheduling algorithm?

b. What is the average turnaround time for these processes with the
SJF scheduling algorithm?

c. The SJF algorithm is supposed to improve performance, but notice


that we chose to run process P1 at time 0 because we did not know
15
16 Chapter 6 CPU Scheduling

that two shorter processes would arrive soon. Compute what the
average turnaround time will be if the CPU is left idle for the first
1 unit and then SJF scheduling is used. Remember that processes
P1 and P2 are waiting during this idle time, so their waiting time
may increase. This algorithm could be known as future-knowledge
scheduling.
Answer:
a. 10.53
b. 9.53
c. 6.86
Remember that turnaround time is finishing time minus arrival time, so
you have to subtract the arrival times to compute the turnaround times.
FCFS is 11 if you forget to subtract arrival time.

6.4 What advantage is there in having different time-quantum sizes at


different levels of a multilevel queueing system?
Answer:
Processes that need more frequent servicing, for instance, interactive
processes such as editors, can be in a queue with a small time quantum.
Processes with no need for frequent servicing can be in a queue with
a larger quantum, requiring fewer context switches to complete the
processing, and thus making more efficient use of the computer.
6.5 Many CPU-scheduling algorithms are parameterized. For example, the
RR algorithm requires a parameter to indicate the time slice. Multilevel
feedback queues require parameters to define the number of queues,
the scheduling algorithms for each queue, the criteria used to move
processes between queues, and so on.
These algorithms are thus really sets of algorithms (for example, the
set of RR algorithms for all time slices, and so on). One set of algorithms
may include another (for example, the FCFS algorithm is the RR algorithm
with an infinite time quantum). What (if any) relation holds between the
following pairs of algorithm sets?
a. Priority and SJF
b. Multilevel feedback queues and FCFS
c. Priority and FCFS
d. RR and SJF

Answer:
a. The shortest job has the highest priority.
b. The lowest level of MLFQ is FCFS.
c. FCFS gives the highest priority to the job having been in existence
the longest.
d. None.
Practice Exercises 17

6.6 Suppose that a scheduling algorithm (at the level of short-term CPU
scheduling) favors those processes that have used the least processor
time in the recent past. Why will this algorithm favor I/O-bound
programs and yet not permanently starve CPU-bound programs?
Answer:
It will favor the I/O-bound programs because of the relatively short CPU
burst request by them; however, the CPU-bound programs will not starve
because the I/O-bound programs will relinquish the CPU relatively often
to do their I/O.
6.7 Distinguish between PCS and SCS scheduling.
Answer:
PCS scheduling is done local to the process. It is how the thread library
schedules threads onto available LWPs. SCS scheduling is the situation
where the operating system schedules kernel threads. On systems using
either many-to-one or many-to-many, the two scheduling models are
fundamentally different. On systems using one-to-one, PCS and SCS are
the same.
6.8 Assume that an operating system maps user-level threads to the kernel
using the many-to-many model and that the mapping is done through
the use of LWPs. Furthermore, the system allows program developers to
create real-time threads. Is it necessary to bind a real-time thread to an
LWP?
Answer:
Yes, otherwise a user thread may have to compete for an available LWP
prior to being actually scheduled. By binding the user thread to an LWP,
there is no latency while waiting for an available LWP; the real-time user
thread can be scheduled immediately.
6.9 The traditional UNIX scheduler enforces an inverse relationship between
priority numbers and priorities: the higher the number, the lower the
priority. The scheduler recalculates process priorities once per second
using the following function:
Priority = (recent CPU usage / 2) + base
where base = 60 and recent CPU usage refers to a value indicating how
often a process has used the CPU since priorities were last recalculated.
Assume that recent CPU usage for process P1 is 40, for process P2 is 18,
and for process P3 is 10. What will be the new priorities for these three
processes when priorities are recalculated? Based on this information,
does the traditional UNIX scheduler raise or lower the relative priority
of a CPU-bound process?
Answer:
The priorities assigned to the processes are 80, 69, and 65 respectively.
The scheduler lowers the relative priority of CPU-bound processes.
4
CHAPTER

Threads
Practice Exercises
4.1 Provide three programming examples in which multithreading provides
better performance than a single-threaded solution.
Answer:

a. A Web server that services each request in a separate thread.


b. A parallelized application such as matrix multiplication where
different parts of the matrix may be worked on in parallel.
c. An interactive GUI program such as a debugger where a thread is
used to monitor user input, another thread represents the running
application, and a third thread monitors performance.

4.2 What are two differences between user-level threads and kernel-level
threads? Under what circumstances is one type better than the other?
Answer:

a. User-level threads are unknown by the kernel, whereas the kernel


is aware of kernel threads.
b. On systems using either M:1 or M:N mapping, user threads are
scheduled by the thread library and the kernel schedules kernel
threads.
c. Kernel threads need not be associated with a process whereas every
user thread belongs to a process. Kernel threads are generally
more expensive to maintain than user threads as they must be
represented with a kernel data structure.

4.3 Describe the actions taken by a kernel to context-switch between kernel-


level threads.
Answer:
Context switching between kernel threads typically requires saving the
value of the CPU registers from the thread being switched out and
restoring the CPU registers of the new thread being scheduled.
11
12 Chapter 4 Threads

4.4 What resources are used when a thread is created? How do they differ
from those used when a process is created?
Answer:
Because a thread is smaller than a process, thread creation typically
uses fewer resources than process creation. Creating a process requires
allocating a process control block (PCB), a rather large data structure.
The PCB includes a memory map, list of open files, and environment
variables. Allocating and managing the memory map is typically the
most time-consuming activity. Creating either a user or kernel thread
involves allocating a small data structure to hold a register set, stack,
and priority.
4.5 Assume that an operating system maps user-level threads to the kernel
using the many-to-many model and that the mapping is done through
LWPs. Furthermore, the system allows developers to create real-time
threads for use in real-time systems. Is it necessary to bind a real-time
thread to an LWP? Explain.
Answer:
Yes. Timing is crucial to real-time applications. If a thread is marked as
real-time but is not bound to an LWP, the thread may have to wait to
be attached to an LWP before running. Consider if a real-time thread is
running (is attached to an LWP) and then proceeds to block (i.e. must
perform I/O, has been preempted by a higher-priority real-time thread,
is waiting for a mutual exclusion lock, etc.) While the real-time thread is
blocked, the LWP it was attached to has been assigned to another thread.
When the real-time thread has been scheduled to run again, it must first
wait to be attached to an LWP. By binding an LWP to a real-time thread
you are ensuring the thread will be able to run with minimal delay once
it is scheduled.
Process
5
CHAPTER

Synchronization
Practice Exercises
5.1 In Section 5.4, we mentioned that disabling interrupts frequently can
affect the system’s clock. Explain why this can occur and how such
effects can be minimized.
Answer:
The system clock is updated at every clock interrupt. If interrupts were
disabled —particularly for a long period of time —it is possible the
system clock could easily lose the correct time. The system clock is
also used for scheduling purposes. For example, the time quantum for a
process is expressed as a number of clock ticks. At every clock interrupt,
the scheduler determines if the time quantum for the currently running
process has expired. If clock interrupts were disabled, the scheduler
could not accurately assign time quantums. This effect can be minimized
by disabling clock interrupts for only very short periods.
5.2 Explain why Windows, Linux, and Solaris implement multiple locking
mechanisms. Describe the circumstances under which they use spin-
locks, mutex locks, semaphores, adaptive mutex locks, and condition
variables. In each case, explain why the mechanism is needed.
Answer:
These operating systems provide different locking mechanisms depend-
ing on the application developers’ needs. Spinlocks are useful for
multiprocessor systems where a thread can run in a busy-loop (for a
short period of time) rather than incurring the overhead of being put in
a sleep queue. Mutexes are useful for locking resources. Solaris 2 uses
adaptive mutexes, meaning that the mutex is implemented with a spin
lock on multiprocessor machines. Semaphores and condition variables
are more appropriate tools for synchronization when a resource must
be held for a long period of time, since spinning is inefficient for a long
duration.
5.3 What is the meaning of the term busy waiting? What other kinds of
waiting are there in an operating system? Can busy waiting be avoided
altogether? Explain your answer.

13
14 Chapter 5 Process Synchronization

Answer:
Busy waiting means that a process is waiting for a condition to be satisfied
in a tight loop without relinquishing the processor. Alternatively, a
process could wait by relinquishing the processor, and block on a
condition and wait to be awakened at some appropriate time in the
future. Busy waiting can be avoided but incurs the overhead associated
with putting a process to sleep and having to wake it up when the
appropriate program state is reached.
5.4 Explain why spinlocks are not appropriate for single-processor systems
yet are often used in multiprocessor systems.
Answer:
Spinlocks are not appropriate for single-processor systems because the
condition that would break a process out of the spinlock can be obtained
only by executing a different process. If the process is not relinquishing
the processor, other processes do not get the opportunity to set the
program condition required for the first process to make progress. In a
multiprocessor system, other processes execute on other processors and
thereby modify the program state in order to release the first process
from the spinlock.
5.5 Show that, if the wait() and signal() semaphore operations are not
executed atomically, then mutual exclusion may be violated.
Answer:
A wait operation atomically decrements the value associated with a
semaphore. If two wait operations are executed on a semaphore when
its value is 1, if the two operations are not performed atomically, then it is
possible that both operations might proceed to decrement the semaphore
value, thereby violating mutual exclusion.
5.6 Illustrate how a binary semaphore can be used to implement mutual
exclusion among n processes.
Answer:
The n processes share a semaphore, mutex, initialized to 1. Each process
Pi is organized as follows:

do {
wait(mutex);

/* critical section */

signal(mutex);

/* remainder section */
} while (true);
7
CHAPTER

Deadlocks
Practice Exercises
7.1 List three examples of deadlocks that are not related to a computer-
system environment.
Answer:

• Two cars crossing a single-lane bridge from opposite directions.


• A person going down a ladder while another person is climbing up
the ladder.
• Two trains traveling toward each other on the same track.
7.2 Suppose that a system is in an unsafe state. Show that it is possible for
the processes to complete their execution without entering a deadlock
state.
Answer:
An unsafe state may not necessarily lead to deadlock, it just means that
we cannot guarantee that deadlock will not occur. Thus, it is possible
that a system in an unsafe state may still allow all processes to complete
without deadlock occurring. Consider the situation where a system has
12 resources allocated among processes P0 , P1 , and P2 . The resources are
allocated according to the following policy:

Max Current Need


P0 10 5 5
P1 4 2 2
P2 9 3 6

Currently there are two resources available. This system is in an


unsafe state as process P1 could complete, thereby freeing a total of
four resources. But we cannot guarantee that processes P0 and P2 can
complete. However, it is possible that a process may release resources
before requesting any further. For example, process P2 could release a
resource, thereby increasing the total number of resources to five. This
19
20 Chapter 7 Deadlocks

allows process P0 to complete, which would free a total of nine resources,


thereby allowing process P2 to complete as well.
7.3 Consider the following snapshot of a system:
Allocation Max Available
ABCD ABCD ABCD
P0 0012 0012 1520
P1 1000 1750
P2 1354 2356
P3 0632 0652
P4 0014 0656
Answer the following questions using the banker’s algorithm:
a. What is the content of the matrix Need?
b. Is the system in a safe state?
c. If a request from process P1 arrives for (0,4,2,0), can the request be
granted immediately?
Answer:
a. The values of Need for processes P0 through P4 respectively are (0,
0, 0, 0), (0, 7, 5, 0), (1, 0, 0, 2), (0, 0, 2, 0), and (0, 6, 4, 2).
b. The system is in a safe state? Yes. With Available being equal to
(1, 5, 2, 0), either process P0 or P3 could run. Once process P3 runs,
it releases its resources, which allow all other existing processes to
run.
c. The request can be granted immediately? This results in the value
of Available being (1, 1, 0, 0). One ordering of processes that can
finish is P0 , P2 , P3 , P1 , and P4 .
7.4 A possible method for preventing deadlocks is to have a single, higher-
order resource that must be requested before any other resource. For
example, if multiple threads attempt to access the synchronization
objects A · · · E, deadlock is possible. (Such synchronization objects may
include mutexes, semaphores, condition variables, and the like.) We can
prevent the deadlock by adding a sixth object F . Whenever a thread
wants to acquire the synchronization lock for any object A · · · E, it must
first acquire the lock for object F . This solution is known as containment:
the locks for objects A · · · E are contained within the lock for object F .
Compare this scheme with the circular-wait scheme of Section 7.4.4.
Answer:
This is probably not a good solution because it yields too large a scope.
It is better to define a locking policy with as narrow a scope as possible.
7.5 Prove that the safety algorithm presented in Section 7.5.3 requires an
order of m × n2 operations.
Answer:
Figure 7.1 provides Java code that implement the safety algorithm of
the banker’s algorithm (the complete implementation of the banker’s
algorithm is available with the source code download).
Practice Exercises 21

for (int i = 0; i < n; i++) {


// first find a thread that can finish
for (int j = 0; j < n; j++) {
if (!finish[j]) {
boolean temp = true;
for (int k = 0; k < m; k++) {
if (need[j][k] > work[k])
temp = false;
}

if (temp) { // if this thread can finish


finish[j] = true;
for (int x = 0; x < m; x++)
work[x] += work[j][x];
}
}
}
}
Figure 7.1 Banker’s algorithm safety algorithm.

As can be seen, the nested outer loops—both of which loop through n


times—provide the n2 performance. Within these outer loops are two
sequential inner loops which loop m times. The big-oh of this algorithm
is therefore O(m × n2 ).
7.6 Consider a computer system that runs 5,000 jobs per month with no
deadlock-prevention or deadlock-avoidance scheme. Deadlocks occur
about twice per month, and the operator must terminate and rerun about
10 jobs per deadlock. Each job is worth about $2 (in CPU time), and the
jobs terminated tend to be about half-done when they are aborted.
A systems programmer has estimated that a deadlock-avoidance
algorithm (like the banker’s algorithm) could be installed in the system
with an increase in the average execution time per job of about 10 percent.
Since the machine currently has 30-percent idle time, all 5,000 jobs per
month could still be run, although turnaround time would increase by
about 20 percent on average.

a. What are the arguments for installing the deadlock-avoidance


algorithm?
b. What are the arguments against installing the deadlock-avoidance
algorithm?

Answer:
An argument for installing deadlock avoidance in the system is that
we could ensure deadlock would never occur. In addition, despite the
increase in turnaround time, all 5,000 jobs could still run.
An argument against installing deadlock avoidance software is that
deadlocks occur infrequently and they cost little when they do occur.
22 Chapter 7 Deadlocks

7.7 Can a system detect that some of its processes are starving? If you answer
“yes,” explain how it can. If you answer “no,” explain how the system
can deal with the starvation problem.
Answer:
Starvation is a difficult topic to define as it may mean different things
for different systems. For the purposes of this question, we will define
starvation as the situation whereby a process must wait beyond a
reasonable period of time —perhaps indefinitely—before receiving a
requested resource. One way of detecting starvation would be to first
identify a period of time — T —that is considered unreasonable. When a
process requests a resource, a timer is started. If the elapsed time exceeds
T, then the process is considered to be starved.
One strategy for dealing with starvation would be to adopt a policy
where resources are assigned only to the process that has been waiting
the longest. For example, if process Pa has been waiting longer for
resource X than process Pb , the request from process Pb would be
deferred until process Pa ’s request has been satisfied.
Another strategy would be less strict than what was just mentioned. In
this scenario, a resource might be granted to a process that has waited less
than another process, providing that the other process is not starving.
However, if another process is considered to be starving, its request
would be satisfied first.
7.8 Consider the following resource-allocation policy. Requests for and
releases of resources are allowed at any time. If a request for resources
cannot be satisfied because the resources are not available, then we check
any processes that are blocked waiting for resources. If a blocked process
has the desired resources, then these resources are taken away from it
and are given to the requesting process. The vector of resources for which
the blocked process is waiting is increased to include the resources that
were taken away.
For example, consider a system with three resource types and the
vector Available initialized to (4,2,2). If process P0 asks for (2,2,1), it gets
them. If P1 asks for (1,0,1), it gets them. Then, if P0 asks for (0,0,1), it
is blocked (resource not available). If P2 now asks for (2,0,0), it gets the
available one (1,0,0) and one that was allocated to P0 (since P0 is blocked).
P0 ’s Allocation vector goes down to (1,2,1), and its Need vector goes up
to (1,0,1).

a. Can deadlock occur? If you answer “yes,” give an example. If you


answer “no,” specify which necessary condition cannot occur.
b. Can indefinite blocking occur? Explain your answer.

Answer:

a. Deadlock cannot occur because preemption exists.


b. Yes. A process may never acquire all the resources it needs if they
are continuously preempted by a series of requests such as those
of process C.
Practice Exercises 23

7.9 Suppose that you have coded the deadlock-avoidance safety algorithm
and now have been asked to implement the deadlock-detection algo-
rithm. Can you do so by simply using the safety algorithm code and
redefining Max[i] = Waiting[i] + Allocation[i], where Waiting[i] is a
vector specifying the resources for which process i is waiting and
Allocation[i] is as defined in Section 7.5? Explain your answer.
Answer:
Yes. The Max vector represents the maximum request a process may
make. When calculating the safety algorithm we use the Need matrix,
which represents Max — Allocation. Another way to think of this is Max
= Need + Allocation. According to the question, the Waiting matrix fulfills
a role similar to the Need matrix, therefore Max = Waiting + Allocation.
7.10 Is it possible to have a deadlock involving only one single-threaded
process? Explain your answer.
Answer:
No. This follows directly from the hold-and-wait condition.

You might also like