Professional Documents
Culture Documents
Project Reports
Class : SE
P1 P2 P3 P4 Total
College of Mathematics and Computer Science
Content
Project 1.................................................................................................................................................. 1
Project 2.................................................................................................................................................. 2
Source code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <semaphore.h>
#define NUM_WAITING_CHAIRS 3
#define DEFAULT_NUM_STUDENTS 5
sem_t sem_students;
sem_t sem_ta;
pthread_mutex_t mutex_thread;
int waiting_room_chairs[3];
int number_students_waiting = 0;
int next_seating_position = 0;
int next_teaching_position = 0;
int ta_sleeping_flag = 0;
int i;
int student_num;
if (argc > 1 ) {
if ( isNumber( argv[1] ) == 1) {
student_num = atoi( argv[1] );
}
else {
printf("Invalid input. Quitting program.");
return 0;
}
}
else {
student_num = DEFAULT_NUM_STUDENTS;
}
int student_ids[student_num];
pthread_t students[student_num];
pthread_t ta;
sem_init( &sem_students, 0, 0 );
sem_init( &sem_ta, 0, 1 );
//Create threads.
pthread_mutex_init( &mutex_thread, NULL );
pthread_create( &ta, NULL, ta_actions, NULL );
for( i = 0; i < student_num; i++ )
{
student_ids[i] = i + 1;
pthread_create( &students[i], NULL, student_actions,
(void*) &student_ids[i] );
}
//Join threads
pthread_join(ta, NULL);
for( i =0; i < student_num; i++ )
{
pthread_join( students[i],NULL );
}
return 0;
}
void* ta_actions() {
while( 1 ) {
ta_sleeping_flag = 0;
sem_wait( &sem_students );
pthread_mutex_lock( &mutex_thread );
waiting_room_chairs[next_teaching_position]=0;
number_students_waiting--;
next_teaching_position = ( next_teaching_position +
1 ) % NUM_WAITING_CHAIRS;
sleep( help_time );
pthread_mutex_unlock( &mutex_thread );
sem_post( &sem_ta );
}
//if no students are waiting
else {
if ( ta_sleeping_flag == 0 ) {
}
void* student_actions( void* student_id ) {
while( 1 ) {
//student is programming.
int time = rand() % 5;
printf( "\tStudent %d is programming for %d seconds.\n",
id_student, time );
sleep( time );
pthread_mutex_lock( &mutex_thread );
waiting_room_chairs[next_seating_position] =
id_student;
number_students_waiting++;
pthread_mutex_unlock( &mutex_thread );
//wake TA if sleeping
sem_post( &sem_students );
sem_wait( &sem_ta );
}
else {
pthread_mutex_unlock( &mutex_thread );
HUNGRY,
EATING,
or THINKING.
mon: ForkMonitor
function DiningPhilosophers ()
print ("Plato\n")
mon.Init ()
mon.PrintAllStatus ()
philospher[0].Init ("Plato")
philospher[0].Fork (PhilosphizeAndEat, 0)
philospher[1].Init ("Sartre")
philospher[1].Fork (PhilosphizeAndEat, 1)
philospher[2].Init ("Kant")
philospher[2].Fork (PhilosphizeAndEat, 2)
philospher[3].Init ("Nietzsche")
philospher[3].Fork (PhilosphizeAndEat, 3)
philospher[4].Init ("Aristotle")
philospher[4].Fork (PhilosphizeAndEat, 4)
endFunction
In a loop, he will think, acquire his forks, eat, and put down his forks.
Var
i: int
Now he is eating
endFor
endFunction
class ForkMonitor
superclass Object
fields
monitorLock: Mutex
Init ()
PrintAllStatus ()
endClass
behavior ForkMonitor
method Init ()
Initialize so that all philosophers are THINKING. Also create the monitor
lock and the 5 condition variables.
var i: int
for i = 0 to 4
startEating[i].Init ()
endFor
monitorLock.Init ()
endMethod
method PickupForks (p: int)
Change his status to HUNGRY and then see if he can begin eating. If he
was not able to begin immediately, then this thread must wait.
monitorLock.Lock ()
self.PrintAllStatus ()
self.CheckAboutEating (p
endIf
monitorLock.Unlock ()
endMethod
This method is called when the philosopher 'p' is done eating. Change
his status. Also, this might make it possible for his left and right
neighbors to begin eating, so check on them.
monitorLock.Lock ()
self.PrintAllStatus ()
self.CheckAboutEating ((p+1) % 5
) self.CheckAboutEating ((p-1) % 5)
monitorLock.Unlock ()
endMethod method
self.PrintAllStatus ()
endIf
endMethod
method PrintAllStatus ()
Print a single line showing the status of all philosophers. '.' means
thinking ' ' means hungry and 'E' means eating Note that this method
is internal to the monitor. Thus, when it is called, the monitor lock will
already have been acquired by the thread. Therefore, this method can
never be re-entered, -- since only one thread at a time may execute
within the monitor. Consequently, printing is safe. This method calls the
"print" routine several times to print a single line, but these will all
happen without interuption.
var
p: int
for p = 0 to 4
case HUNGRY:
break
case EATING:
break
case THINKING:
break
endSwitch
endFor
nl ()
endMethod
Project 3—Producer–Consumer Problem
There are several consumers. Each consumer is a thread which
executes an inifinite loop. During each iteration of its loop, a consumer
will remove whatever character is next in the buffer and will print it.
BUFFER_SIZE = 5
var
bufferSize: int = 0
bufferNextIn: int = 0
bufferNextOut: int = 0
function ProducerConsumer ()
buffer = new array of char {BUFFER_SIZE of '?'}
bufferLock.Init ()
bufferContents.Init (0)
bufferSpaceLeft.Init (BUFFER_SIZE)
thArray[0].Fork (Consumer, 1
thArray[1].Fork (Consumer, 2)
thArray[2].Fork (Consumer, 3)
thArray[3].Fork (Producer, 1)
thArray[4].Fork (Producer, 2)
thArray[5].Fork (Producer, 3)
thArray[6].Fork (Producer, 4)
ThreadFinish ()
endFunction
var
i: int
for i = 1 to 5
Perform synchronization
bufferSpaceLeft.Down()
bufferLock.Lock()
buffer [bufferNextIn] = c
bufferSize = bufferSize + 1
PrintBuffer (c)
Perform synchronization
bufferContents.Up()
bufferLock.Unlock()
endFor
endFunction
var
c: char
while true
Perform synchroniztion...
bufferContents.Down()
bufferLock.Lock()
r c = buffer [bufferNextOut]
bufferSize = bufferSize - 1
PrintBuffer (c)
Perform synchronization...
bufferSpaceLeft.Up()
bufferLock.Unlock()
endWhile
endFunction
function PrintBuffer (c: char)
This method prints the buffer and what we are doing to it. Each line
should have
Var
i, j: int
printChar (c)
nl ()
j = bufferNextOut
for i = 1 to bufferSize
printChar (buffer[j])
j = (j + 1) % BUFFER_SIZE
endFor
for i = 1 to BUFFER_SIZE-bufferSize
printChar (' ')
endFor
endFunction