Part 1.
__T_ A process has a stack for every thread it contains.
__T_ Race conditons are more likely to happen in
multiprocessor machines.
__F_ In POSIX threads, the thread calling fork will create
a child process that is a copy of the parent inclluding all the
threads in the
process.
(only in Solaris and by calling thr_create)
Explain what is deadlock and what is starvation and give an example of each.
Deadlock happens when threads are waiting for resources that
will not be available to them and will not proceed. The only way
to end the deadlock is to kill the process. An example would be
the Dining Philosophers Problem where every philosopher waits for
a fork and no one is willing to give up the fork he/she is
holding.
Starvation is not as serious as deadlock. It is a condition where
a thread might take a long time to obtain resources because there
are constantly other threads holding the locks. An example would
be the read/write locks.
What are the advantages and disadvantages of using threads vs. using processes?
Threads | Processes | ||
Advantages | Disadvantages | Advantages | Disadvantages |
|
|
|
|
In the following code,
T1: |
T2: |
T3: |
a) give a sequence of steps using the letters at the left of each statement that will cause the threads to get into a deadlok. (Example: T1a, T2d, T3g ... etc)
T1: |
T2: |
T3: |
b) Draw the graph representation of the deadlock.
m3->T1
->m5->T2->m4->T3
^
|
|---------------------------------
c) Rewrite the code to prevent the deadlock.
T1: |
T2: |
T3: |
7.Assume that the following code for adding items into an array. addToArray will return the index in the array where the value was added or -1 if the buffer is full. a) What problems do you see can happen if multiple threads try to run it? Rewrite the code to solve the problem.
a) If multiple threads try to run it, the array data structure
can get messed up. For example:
First thread reaches the line “array[count] = value”, then context
switch happens. Second thread reaches the same line and overwrites
array[count]. The first value added is then lost. Also the return
count-1; should be
substituted by return tmp; and have tmp be set to count-1 before
the mutex_lock.
} |
New Code int tmp = count-1; pthread_mutex_unlock(&_mutex); } |
Write a program "grepsort arg1 arg2 arg3" that implements the command "grep arg1 | sort < arg2 >> arg3". The program should not return until the command finishes. "arg1", "arg2", and "arg3" are passed as arguments to the program. Example of the usage is "grepsort hello infile outfile". This command will print the entries in file infile that contain the string hello and will append the output sorted to file outfile. Do error checking. Notice that the output is appended to arg3. |
#include <stdio.h> |
Using C++ and Semaphores write a class SynchronizedStackSemaphores of int values where pop() will block if the stack is empty and push will block if the stack is full. Write the member variables that you think are necessary. Implement the stack with an array of int's and allocate it dynamically in the constructor. Hint: Use the "Bounded Buffer Problem" with semaphores as an example in your implementation. |
#include <synch.h> #include <pthread.h> class SynchronizedStackSemaphores { // Add your member variables here int top; int * stack; sema_t emptySem, fullSem; pthread_mutex_t lock; public: SynchronizedStackSemaphores(int maxStackSize); void push(int val); int pop(); }; SynchronizedStackSemaphores::SynchronizedStackSemaphores(int maxStackSize) { top = 0; stack = new int[maxStackSize]; sema_init(&emptySem, 0, USYNC_THREAD, NULL); sema_init(&fullSem, maxStackSize, USYNC_THREAD, NULL); pthread_mutex_init(&lock, NULL); } void SynchronizedStackSemaphores::push(int val) { sema_wait(&fullSem); pthread_mutex_lock(&lock); stack[top] = val; top++; pthread_mutex_unlock(&lock); sema_post(&emptySem); } int SynchronizedStackSemaphores::pop(){ sema_wait(&emptySem); pthread_mutex_lock(&lock); int retval = stack[top-1]; top--; pthread_mutex_unlock(&lock); sema_post(&fullSem); return retval; } |