For the homework questions below, if you believe that you cannot answer a question without making some assumptions, state those assumptions in your answer.
5.1 Provide two programming examples of multithreading that improve performance over a single-threaded solution.
5.2 Provide two programming examples of multithreading that do not improve performance over a single-threaded solution.
5.3 What are the differences between user-level threads and kernel-level threads? Under what circumstances is one type better than the other?
#include <signal.h>
#include <sys/wait.h>
main {
for ( ; ; ) {
if (! fork() ) { exit(0); }
sleep(1);
}
}
Hints: You will need two binary semaphores to implement one counting semaphore. There is no need to use a queue - the queueing on the binary semaphores is all you'll need. You should not use busy waiting. The wait() operation for the counting semaphore will first wait on one of the two binary semaphores, and then on the other. The wait on the first semaphore implements the queueing on the counting semaphore and the wait on the second semaphore is for mutual exclusion.
struct lock {
...
}
void acquire (struct lock *) {
...
}
void release (struct lock *) {
...
}
If you did this, you would notice the following behavior: for awhile - some seconds - the number of critical section entries per second will be very high. At some point, though, the number of critical section entries per second would suddenly drop to a much lower rate - indeed, many thousands of times slower.
(If you wish, give it a try!)
Explain why this happens.