0% found this document useful (0 votes)
60 views

OS Lab 6

The document contains code for implementing the producer-consumer problem using threads and synchronization primitives like mutex locks and condition variables. It defines functions for the producer thread that writes items to a shared queue and the consumer thread that reads from the queue. The threads signal each other using condition variables when the queue becomes full or empty to ensure only one thread accesses the shared queue at a time.

Uploaded by

Jenish Bhanawat
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
60 views

OS Lab 6

The document contains code for implementing the producer-consumer problem using threads and synchronization primitives like mutex locks and condition variables. It defines functions for the producer thread that writes items to a shared queue and the consumer thread that reads from the queue. The threads signal each other using condition variables when the queue becomes full or empty to ensure only one thread accesses the shared queue at a time.

Uploaded by

Jenish Bhanawat
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 17

RIYA JAIN

19103029
B1 Batch
OSSP Lab 6

Ques 1:
#include <pthread.h>
#include <unistd.h>
#include <semaphore.h>
#include <stdio.h>

#define N 5
#define THINKING 2
#define HUNGRY 1
#define EATING 0
#define LEFT (phnum + 4) % N
#define RIGHT (phnum + 1) % N

int state[N];
int phil[N] = {0, 1, 2, 3, 4};

sem_t mutex;
sem_t S[N];

void test(int phnum) {


if (state[phnum] == HUNGRY && state[LEFT] != EATING && state[RIGHT] != EATING) {
// state that eating
state[phnum] = EATING;
sleep(2);
printf("Philosopher %d takes fork %d and %d\n", phnum + 1, LEFT + 1, phnum + 1);
printf("Philosopher %d is Eating\n", phnum + 1);
// sem_post(&S[phnum]) has no effect
// during takefork
// used to wake up hungry philosophers
// during putfork
sem_post(&S[phnum]);
}
}

// take up chopsticks
void take_fork(int phnum) {
sem_wait(&mutex);
// state that hungry
state[phnum] = HUNGRY;
printf("Philosopher %d is Hungry\n", phnum + 1);
// eat if neighbours are not eating
test(phnum);
sem_post(&mutex);
// if unable to eat wait to be signalled
sem_wait(&S[phnum]);
sleep(1);
}

// put down chopsticks


void put_fork(int phnum) {
sem_wait(&mutex);
// state that thinking
state[phnum] = THINKING;
printf("Philosopher %d putting fork %d and %d down\n", phnum + 1, LEFT + 1,
phnum + 1);
printf("Philosopher %d is thinking\n", phnum + 1);
test(LEFT);
test(RIGHT);
sem_post(&mutex);
}

void *philosopher(void *num) {


while (1) {
int *i = num;
sleep(1);
take_fork(*i);
sleep(0);
put_fork(*i);
}
}

int main() {
int i;
pthread_t thread_id[N];
// initialize the semaphores
sem_init(&mutex, 0, 1);
for (i = 0; i < N; i++)
sem_init(&S[i], 0, 0);
for (i = 0; i < N; i++) {
// create philosopher processes
pthread_create(&thread_id[i], NULL, philosopher, &phil[i]);
printf("Philosopher %d is thinking\n", i + 1);
}
for (i = 0; i < N; i++)
pthread_ join(thread_id[i], NULL);
}

Ques 2:
// here I used an array to implement the queu
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define QUEU_SIZE 5
char queue [QUEU_SIZE] ;
int front = 0 , rear = 0 ; // pointrs to front and rear of the queu
int items = 0 ; // number of items in queu
int done = 1 ; // to show that the input file is finished to read

pthread_mutex_t mutex ;
pthread_cond_t item_available ; // condition variable to show producer put a word in
queu
pthread_cond_t space_available ; // condition variable to show consumer delete a
word from queu

void * p_thread() ; // the producer


void * c_thread() ; // the consumer

int main(int argc, char *argv[]) {


pthread_t producer , consumer;
//pthread_init();
pthread_cond_init (&item_available, NULL) ;
pthread_cond_init (&space_available, NULL) ;
pthread_mutex_init (&mutex, NULL) ;
if( pthread_create ( &producer , NULL, p_thread, NULL)) { // create producer
fprintf(stderr, "Error creating producer thread\n");
return 1;
}
if( pthread_create ( &consumer , NULL, c_thread, NULL)) { // create the consumer
fprintf(stderr, "Error creating consumer thread\n");
return 1;
}
if ( pthread_ join ( producer , NULL ) ) { // wait for all threads to finish
fprintf(stderr, "Error joining thread\n");
return 2;
}
if ( pthread_ join ( consumer , NULL ) ) {
fprintf(stderr, "Error joining consumer\n");
return 2;
}
return 0;
}
void * p_thread() {
FILE *fp = fopen("string.txt","r");
char c ;
c = getc(fp);
while (c != EOF) {
//1
sleep(1);
pthread_mutex_lock (&mutex) ;
//2
printf (" front<%d> rear<%d> items <%d>\n", front , rear , items ) ;
while ( items >= QUEU_SIZE ) // while there is no space in queu to write
pthread_cond_wait ( &space_available , &mutex ) ;
//3
printf (" front<%d> rear<%d> items <%d>\n", front , rear , items ) ;
// now we cAN write in queue
queue [front] = c ;
front ++ ;
if(front==QUEU_SIZE) front = 0 ;
items ++ ;
printf (" character write to queue: <%c>\n" , c ) ;
printf (" wake up a consumer \n" ) ;
pthread_cond_signal(&item_available); // wake up a consumer
pthread_mutex_unlock (&mutex) ;
sleep (1);
c = getc(fp);
}
pthread_mutex_lock (&mutex) ;
done = 0 ; // we should tell the consumer that the file is finished
pthread_cond_signal(&item_available);
pthread_mutex_unlock (&mutex) ;
fclose (fp);
//printf ("hello prof. Song Jiang\n") ;
//return NULL;
pthread_exit (0);
}

void * c_thread() {
FILE* output = fopen ("string_result.txt" , "w") ;
//4
while ( done != 0 ) { // while there is something to read
pthread_mutex_lock (&mutex) ;
//5
printf ("front<%d> rear<%d> items <%d>\n", front , rear , items ) ;
while ( items <= 0 && done!= 0 ) // while there is no character in queu to read
we should wait
pthread_cond_wait ( &item_available , &mutex ) ;
//6
printf ("front<%d> rear<%d> items <%d>\n", front , rear , items ) ;

// read the character and write it:


char c = queue [rear] ;
rear ++ ;
if (rear==QUEU_SIZE) rear = 0 ;
items -- ;
printf ("character read from queue: <%c>\n" , c ) ;
printf ("wake up a producer \n" ) ;
fprintf(output,"%c",c) ;
pthread_cond_signal(&space_available); // send signal for producer to show
that thre is space
pthread_mutex_unlock (&mutex) ;
}
fclose (output) ;
//return NULL;
pthread_exit (0);
}
Ques 3:
monitor ProducerConsumer
condition full,
empty;
int count;

procedure enter();
{
if (count == N)
wait(full); // if buffer is full, block
put_item(widget); // put item in buffer
count = count + 1; // increment count of full slots
if (count == 1)
signal(empty); // if buffer was empty, wake consumer
}

procedure remove();
{
if (count == 0)
wait(empty); // if buffer is empty, block
remove_item(widget); // remove item from buffer
count = count - 1; // decrement count of full slots
if (count == N - 1)
signal(full); // if buffer was full, wake producer
}

count = 0;
end monitor;

Producer();
{
while (TRUE)
{
make_item(widget); // make a new item
ProducerConsumer.enter; // call enter function in monitor
}
}

Consumer();
{
while (TRUE)
{
ProducerConsumer.remove; // call remove function in monitor
consume_item; // consume an item
}
}

Ques 4:
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <time.h>
#include <unistd.h>

int accessSeats[2];
int customers[2];
int barber[2];
int freeaccessSeats[2];

void randomWait();
void barber_process();
void customer_process();

void V(int pd[]) {


int a = 1;
write(pd[1], &a, sizeof(int));
}
void P(int pd[]) {
int a;
read(pd[0], &a, sizeof(int));
}

void main() {
int i;
pipe(accessSeats);
pipe(customers);
pipe(barber);
pipe(freeaccessSeats);

V(accessSeats);

int num = 3; // waiting room seats = 3


write(freeaccessSeats[1], &num, sizeof(int));

if (fork() == 0) {
srand(time(0) + 1); //Random Seed
barber_process();
return;
}

for (i = 1; i <= 5; i++) { // five customers


if (fork() == 0) {
srand(time(0) + 2 * i); // different random seed
customer_process();
return;
}
}
sleep(10);
printf("\ndone\n\n");
}
void barber_process() {
int i;
int num; //number of free seats
for (i = 1; i <= 10; ++i) {
printf("Barber %d is trying to get a customer\n", i);
P(customers);
printf("Barber %d is waiting for the seat to become free\n", i);
P(accessSeats);
read(freeaccessSeats[0], &num, sizeof(int));
num++;
write(freeaccessSeats[1], &num, sizeof(int));
printf("Barber %d is increasing the number of free accessSeats to %d\n", i, num);
V(barber);
V(accessSeats);
printf("Barber is now cutting hair %d\n", i);
randomWait();
}
}

void customer_process() {
int i;
int num;
for (i = 1; i <= 2; ++i) {
printf("New customer trying to find a seat\n");
P(accessSeats);
read(freeaccessSeats[0], &num, sizeof(int));
if (num > 0) {
num--;
write(freeaccessSeats[1], &num, sizeof(int));
printf("Customer left seat in waiting room. The total free accessSeats are now:
%d\n", num);
V(customers);
V(accessSeats);
printf("Customer is now waiting for the barber\n");
P(barber);
printf("Customer is now getting a hair cut\n");
}
else {
write(freeaccessSeats[1], &num, sizeof(int));
V(accessSeats);
printf("No free chairs in waiting room\n");
}
randomWait();
}
}

void randomWait() { // random delay


int delay;
delay = random() % 9999999999;
printf(" - wait: %d\n", delay); // debugging - value of wait time
}

You might also like