P(s1);
a++;
P(s2);
v++;
V(s2);
V(s1);
(s1, s2 are semaphores). All variables are
automatic. Now, consider two threads running this fragment of code
simultaneously, can there be a deadlock? Why,
or why not?
Solution:
Both semaphores will be acquired in the same order by both threads. Since this is a linear order, there can be no situation where a deadlock could occur.
if(a > 0)
P(s1);
else
P(s2);
b++;
P(s3);
if(b < 0 && a <= 0)
P(s1);
else if(b >= 0 && a > 0)
P(s2);
else
P(s4);
a++;
V(s4);
V(s3);
V(s2);
V(s1);
s1, s2, s3 and s4 are semaphores. All variables are automatic. Now, consider two threads running this fragment of code simultaneously, can there be a deadlock? Why, or why not?
Solution:
Yes, there can be a deadlock. Consider the scenario where thread 1 starts by locking semaphore s1 then gets switched out while thread 2 runs. Thread 2 may start running with variable a set to 0 (remember, because the variables are automatic, each thread has its own independent set). Thread 2 will acquire semaphore s2, then proceeds to acquire s3. Then, if (b<0 && a <=0), it will try to acquire s1. This forces thread 2 to wait for thread 1 which holds this semaphore. Now, thread 1 may proceed but will block when it tries to acquire semaphore s3. This forms a cyclical wait, and a deadlock occurs.
while(1)where Table is a shared object that encapsulates the system's shared state. As a result of the function Table::Work(), the philosopher makes enough soup to fill a bowl. Similarly, the result of the function Table::Eat() is that a philosopher picks a bowl and consumes all the soup in it. Note that there is no correspondence between bowls and philosophers, i.e., a philosopher will eat from any available bowl that contains soup, and will fill any available empty bowl.
{
flip the coin
if(head) Table.Work()
else Table.Eat()
Think()
}
Solution:
Table constructor
lock = new Lock();
bowlEmpty = new Condition();
bowlfull = new Condition();
int full = 0;Table::Work()
lock.acquire();
while(full == 5) {
bowlEmpty.wait(&lock);
}
full++;
bowlFull.signal();
lock.release();Table::Eat()
lock.acquire();
while (full == 0) {
bowlFull.wait(&lock);
}
full--;
bowlEmpty.signal();
lock.release();
Solution:
Yes. Suppose the bowls start empty and four tails come up in a row. Then four
threads are waiting in Eat().
The next flip must be heads, and a thread will Work. Then, three threads must
be waiting in Eat(), and 2 threads in the main loop. Now suppose two more
tails come up in a row. Then all five threads are waiting
in Eat(), and no thread remains to Work(). Silly philosophers.
Solution:
False.
Solution:
In a safe state there exists a safe sequence -- an ordered sequence of
resource grants that would allow each process that currently holds any
resources to acquire that process's maximum resource allocation. In an
unsafe state, no such sequence exists. Thus, an OS can always prevent
deadlock when a system is in a safe state by only granting resources that
keep the system in a safe state. Conversely, if the system is in an
unsafe state, there exists at least one sequence of requests that will
deadlock the system regardless of what the OS does.
Solution:
Priority inversion is a program bug in which a high priority thread waits for a lock that
is held by a low priority thread and the low priority thread is unable to release the lock
because a medium priority thread is using the CPU (or other required resources). In effect,
the high priority thread is waiting for the medium priority thread.