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

Operating Systems Assignment 1

This document contains code for implementing producer consumer problem using semaphores and mutex locks in C. It defines functions for the producer to produce items and add them to a shared buffer and for the consumer to consume items and remove them from the buffer. It initializes the necessary variables like mutex, number of full/empty slots. The main function runs a loop taking user input to call the producer or consumer functions, ensuring mutual exclusion using #pragma omp critical.

Uploaded by

Shivi Mehrotra
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
41 views

Operating Systems Assignment 1

This document contains code for implementing producer consumer problem using semaphores and mutex locks in C. It defines functions for the producer to produce items and add them to a shared buffer and for the consumer to consume items and remove them from the buffer. It initializes the necessary variables like mutex, number of full/empty slots. The main function runs a loop taking user input to call the producer or consumer functions, ensuring mutual exclusion using #pragma omp critical.

Uploaded by

Shivi Mehrotra
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 15

OSSP LAB

WEEK 7
Name:Shivi Mehrotra
Batch: B3
Enrollment no.: 20103064

1.

#include <pthread.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);
2.
// C program for the above approach

#include <stdio.h>
#include <stdlib.h>

// Initialize a mutex to 1 int


mutex = 1;

// Number of full slots as 0


int full = 0;

// Number of empty slots as size


// of buffer int empty
= 10, x = 0;

// Function to produce an item and //


add it to the buffer
void producer()
{
// Decrease mutex value by 1
--mutex;

// Increase the number of full


// slots by 1
++full;

// Decrease the number of empty


// slots by 1
--empty;

// Item produced x++;


printf("\nProducer produces" "item
%d",
x);

// Increase mutex value by 1


++mutex;
}
// Function to consume an item and
// remove it from buffer void
consumer()
{
// Decrease mutex value by 1
--mutex;

// Decrease the number of full


// slots by 1
--full;

// Increase the number of empty


// slots by 1
++empty; printf("\nConsumer
consumes "
"item %d",
x);
x--;
// Increase mutex value by 1
++mutex;
}
// Driver Code
int main()
{ int n, i;
printf("\n1. Press 1 for Producer"
"\n2. Press 2 for Consumer"
"\n3. Press 3 for Exit");
// Using '#pragma omp parallel for' //
can give wrong value due to
// synchronization issues.

// 'critical' specifies that code is


// executed by only one thread at a
// time i.e., only one thread enters
// the critical section at a given time
#pragma omp critical

for (i = 1; i > 0; i++) {

printf("\nEnter your choice:"); scanf("%d",


&n);

// Switch Cases
switch (n) {
case 1:

// If mutex is 1 and empty


// is non-zero, then it is //
possible to produce if
((mutex == 1) && (empty
!= 0)) { producer();
}

// Otherwise, print buffer


// is full
else { printf("Buffer is full!");
}
break;

case 2:

// If mutex is 1 and full


// is non-zero, then it is
// possible to consume
if ((mutex == 1) &&
(full != 0)) {
consumer();
}

// Otherwise, print Buffer // is


empty else { printf("Buffer is
empty!");
}
break;
// Exit Condition
case 3: exit(0);
break;
}
}
}

3.
// C program for the above approach

#include <stdio.h>
#include <stdlib.h>

// Initialize a mutex to 1
int mutex = 1;

// Number of full slots as 0 int


full = 0;

// Number of empty slots as size


// of buffer int empty
= 10, x = 0;

// Function to produce an item and //


add it to the buffer
void producer()
{
// Decrease mutex value by 1
--mutex;
// Increase the number of full
// slots by 1
++full;

// Decrease the number of empty


// slots by 1
--empty;

// Item produced x++;


printf("\nProducer produces" "item
%d",
x);

// Increase mutex value by 1


++mutex;
}
// Function to consume an item and //
remove it from buffer
void consumer()
{
// Decrease mutex value by 1
--mutex;

// Decrease the number of full


// slots by 1
--full;

// Increase the number of empty


// slots by 1
++empty;
printf("\nConsumer consumes " "item
%d",
x);
x--;
// Increase mutex value by 1
++mutex;
}
// Driver Code int
main()
{ int n, i;
printf("\n1. Press 1 for Producer"
"\n2. Press 2 for Consumer"
"\n3. Press 3 for Exit");

// Using '#pragma omp parallel for' //


can give wrong value due to
// synchronization issues.
// 'critical' specifies that code is
// executed by only one thread at a
// time i.e., only one thread enters
// the critical section at a given time
#pragma omp critical

for (i = 1; i > 0; i++) {

printf("\nEnter your choice:"); scanf("%d",


&n);

// Switch Cases
switch (n) {
case 1:

// If mutex is 1 and empty


// is non-zero, then it is
// possible to produce
if ((mutex == 1)
&& (empty != 0)) {
producer();
}

// Otherwise, print buffer


// is full else { printf("Buffer
is full!");
}
break;
case 2:

// If mutex is 1 and full


// is non-zero, then it is
// possible to consume
if ((mutex == 1)
&& (full != 0)) {
consumer();
}
// Otherwise, print Buffer // is
empty else { printf("Buffer is
empty!");
}
break;

// Exit Condition
case 3: exit(0);
break;
}
}
}

4.
// C++ program to illustrate Banker's Algorithm
#include<iostream>
using namespace std;

// Number of processes const


int P = 5;

// Number of resources const


int R = 3;

// Function to find the need of each process void


calculateNeed(int need[P][R], int maxm[P][R], int
allot[P][R]) {
// Calculating Need of each P
for (int i = 0 ; i < P ; i++) for (int
j = 0 ; j < R ; j++)

// Need of instance = maxm instance -


// allocated instance
need[i][j] = maxm[i][j] - allot[i][j];
}
// Function to find the system is in safe state or not
bool isSafe(int processes[], int avail[], int maxm[][R],
int allot[][R])
{
int need[P][R];

// Function to calculate need matrix calculateNeed(need,


maxm, allot);

// Mark all processes as infinish bool


finish[P] = {0};

// To store safe sequence int


safeSeq[P];

// Make a copy of available resources


int work[R]; for (int i =
0; i < R ; i++) work[i] =
avail[i];
// While all processes are not finished
// or system is not in safe state. int
count = 0;
while (count < P)
{
// Find a process which is not finish and //
whose needs can be satisfied with current
// work[] resources. bool found = false; for
(int p = 0; p < P; p++)
{
// First check if a process is finished,
// if no, go for next condition if
(finish[p] == 0)
{
// Check if for all resources of
// current P need is less
// than work
int j;
for (j = 0; j < R; j++) if
(need[p][j] > work[j])
break;

// If all needs of p were satisfied. if


(j == R)
{
// Add the allocated resources of
// current P to the available/work
// resources i.e.free the
resources for (int k = 0 ; k < R ;
k++) work[k] += allot[p][k];

// Add this process to safe sequence.


safeSeq[count++] = p;

// Mark this p as finished finish[p]


= 1;

found = true;
}
}
}
// If we could not find a next process in safe //
sequence.
if (found == false)
{
cout << "System is not in safe state";
return false;
}
}

// If system is in safe state then // safe


sequence will be as below cout <<
"System is in safe state.\nSafe"
" sequence is: "; for (int i
= 0; i < P ; i++) cout <<
safeSeq[i] << " ";

return true;
}

// Driver code
int main()
{
int processes[] = {0, 1, 2, 3, 4};

// Available instances of resources


int avail[] = {3, 3, 2};

// Maximum R that can be allocated


// to processes int
maxm[][R] = {{7, 5, 3},
{3, 2, 2},
{9, 0, 2},
{2, 2, 2},
{4, 3, 3}};

// Resources allocated to processes int


allot[][R] = {{0, 1, 0},
{2, 0, 0},
{3, 0, 2},
{2, 1, 1},
{0, 0, 2}};

// Check system is in safe state or not


isSafe(processes, avail, maxm, allot);

return 0;
}
5.
// Java program to illustrate Deadlock
situation class DeadlockDemo extends
Thread { static Thread mainThread;
public void run()
{
System.out.println("Child Thread waiting for" +
" main thread completion");

try {

// Child thread waiting for completion


// of main thread mainThread.join();
}
catch (InterruptedException e) {
System.out.println("Child thread execution" +
" completes");
}
}
public static void main(String[] args) throws
InterruptedException
{
DeadlockDemo.mainThread = Thread.currentThread();
DeadlockDemo thread = new DeadlockDemo();
thread.start();
System.out.println("Main thread waiting for " +
"Child thread completion");

// main thread is waiting for the completion


// of Child thread thread.join();

System.out.println("Main thread execution" +


" completes");
}
}
6.

Semaphore Customers = 0;
Semaphore Barber = 0; Mutex
Seats = 1;
int FreeSeats = N;

Barber { while(true)
{

/* waits for a customer (sleeps). */ down(Customers);

/* mutex to protect the number of available seats.*/ down(Seats);

/* a chair gets free.*/ FreeSeats++;

/* bring customer for haircut.*/


up(Barber);

/* release the mutex on the chair.*/ up(Seats);


/* barber is cutting hair.*/
}
}
Customer { while(true) {
/* protects seats so only 1 customer tries to
sit in a chair if that's the case.*/ down(Seats);
//This line should not be here. if(FreeSeats >
0) {

/* sitting down.*/ FreeSeats--;

/* notify the barber. */ up(Customers);

/* release the lock */ up(Seats);

/* wait in the waiting room if barber is busy. */

down(Barber);
// customer is having hair cut
} else {
/* release the lock */
up(Seats);
// customer leaves
}
}
}

You might also like