Exercises On Sychronization2023 Solutions
Exercises On Sychronization2023 Solutions
Process 1 Process 2
for ( ; ; ) { for ( ; ; ) {
wait(S); wait(Q);
print(a); print(b);
signal(Q); signal(S);
} }
2. The pseudocode below illustrates the basic push() and pop() operations
of an array-based stack. Assuming that this algorithm is used in a
concurrent environment, answer the following questions:
(a) Which data have a race condition? sol: problem with the top
variable
(b) How could the race condition be fixed? Sol. By making the update
of this variable a critical section. The code line of top + + should
be proceeded by a synchronization such as wait(mutex) followed
by signal(mutex) where mutex is a binary semaphore initialized
to 1. Similarly with top − − using the same mutex semaphore.
push(item) {
if (top < SIZE) {
stack[top] = item;
top++;
}
else ERROR
}
pop() {
if (!empty()) {
top = top - 1;
return stack[top];
}
else ERROR
}
is empty() {
if (top == 0) return true;
else return false;
}
P1 P2 P3
print(Y) print(O) print(U)
print(ARE) print(OK) print(NOW)
Use semaphores and semaphore initializations such that the result printed
is YOU ARE OK NOW
SoL: s1 = 0; s2 = 0; s3 = 0
P1 P2 P3
wait(s2) wait(s3)
print(Y) print(O) print(U)
signal(s2) signal(s3) signal(s1)
wait(s1) wait(s2) wait(s3)
print(ARE) print(OK) print(NOW)
signal(s2) signal(s3)
P1 P2 P3
OP1 OP2 OP3
P1 P2 P3
wait(s) wait(s) OP3
signal(s)
OP1 OP2
signal(s) signal(s)
6. Consider the following two processes that run concurrently and where
initially y = z = 0
P1 P2
int x; y = 1;
x = y + z; z = 2;
(a) What are the possible final values for x? Sol. 0, 1, 2 and 3. x = 2
when P1 is de-scheduled after copying y = 0, then P2 is run, it
changes the value of y and z, then P1 run again, copy z = 2, then
x = (y = 0) + (z = 2).
(b) Is it possible, using semaphore, to have only two values for x? If
so, list the two values and explain how you can get them. Sol:
From the semantic of the code, either y+z is performed with the
initial value of the variables or after they have been modified by
process P2 . Using semaphores we can select either way by having
process P2 blocked so that P1 executes first, thus x = 0 or block
process P1 until process P2 has executed, then x = 3.
P1 P2
print(A); print(E);
print(B); print(F);
print(C); print(G);
P1 P2
print(A); print(E);
signal(s1 );
wait(s1 );
print(B); print(F);
signal(s2 );
wait(s2 );
print(C); print(G);
P1 P2
int x; y = 2;
x = y + z; z = 3;
sol: 2, 3, 4, 5
10. The semantic of locks is as following
acquire(lock)
critical section
release(lock)
Assume a computer system that has only one CPU. Can the lock be
implemented as following, explain why or why not.
void acquire(lock) {
diseable interrupts;
}
void release (lock) {
enable interrupts;
}
sol: Let T1 be a thread executing code in a critical section after ob-
taining a lock. The thread T1 can still be de-scheduled. For example,
the quantum time of T1 expires before T1 complete the execution of the
code in the critical section. If the instruction disable interrupts above
was executed after acquiring the lock, it will prevent the de-scheduling
of thread T1 as most of the interrupts will be blocked, particularly inter-
rupts issued by the hardware timer that signal the end of a quantum
time. So yes it can be implemented this way. However only kernel
threads can disable interrupts, this instruction cannot be called by a
user thread. OS kernels constantly disable interrupts as a synchroniza-
tion mechanism while executing kernel threads.
12. Consider the code below for the readers/writer problem discussed in
the lecture, where multiple threads are executing reader and writer
functions to read/write the shared data base. To prevent that writ-
ers access in same time as readers, the following semaphores are used:
Binary semaphore rw mutex initialized to 1, Binary semaphore mu-
tex initialized to 1, Counting semaphore readers initialized to n, int
read count initialized to 0. Unfortunately the way the semaphores are
used below does not work. Explain what is the problem
sol: The rw mutex should be acquired by the first reader, reader 1. But
because reader 1 release mutex before acquiring rw mutex, there could
be a context switch allowing a second reader, reader 2, to enter the DB.
Since readcount is now equal to 2, the if condition is not executed by
reader 2, it enters the DB. Meanwhile, a writer can catch the rw mutex
before reader 1, the writer will enter the DB while there is a reader in
it.
13. The solution in class to the readers/writer problem can starve the
writer. One solution to this problem will consists to add one semaphore
that both writers and readers threads will have to query. Show how this
solution could be implemented and explain why it solves the starvation
problem for the writers.
sol: Add a new binary semaphore w mutex initialized to 0 and use it as
follow for the writer. For the reader it will start with wait(w mutex);
signal(w mutex);. In this way both readers and writers compete for the
same semaphore. If a writer want to access the DB, and signal(w mutex)
= 0; it will capture the mutex and then any reader will be blocked from
accessing the DB until all the readers in the DB has exited and the
writer has completed its task and release w mutex (signal(w mutex)).
while (true) {
wait(rw_mutex);
wait(w_mutex);
/* writing is performed */
...
signal(rw_mutex);
signal(w_mutex);
}
14. The following C code is a non-atomic implementation of semaphores.
Given the non-atomicity of the semaphores, there exist scenarios where
context switches will cause two threads T1 and T2 that synchronize
with the same semaphore S to enter in a same critical section. Which
one of the scenarios below can cause this situation to occur?
sol: It is c, Once pass the while loop, thread T1 is clearly in the critical
section but the value of the semaphore has not been decremented. Thus
T2 can enter the critical section as well.
(a) Nothing special will happen, T1 will resume executing the code in
its critical section once it is re-scheduled
(b) The system can potentially deadlock. Because a mutex is a spin-
lock, if a second thread T2 seeks to acquire the mutex lock L0 ,
T2 will monopolize the CPU, T1 will never return into its critical
section and will never release the lock L0 , deadlock
(c) Context switch within a critical section is against mutual exclu-
sion, it allows threads to re-enter a critical section without re-
questing a lock