Bahria University, Lahore Campus
Department of Computer Sciences
Lab Journal 10
(Spring 2022)
Course: Operating Systems Date:
Course Code: CSL -320 Max Marks: 20
Faculty’s Name: Ms. Nighat Usman
Name: Abdullah Arshad________________________________
Enroll No: 03-134201-030 _______________________
Objective(s):
Introduction to Dining Philosophers and Deadlock Charaterization
Compiler:
Ubuntu, Terminal, Nano, G++
Important Note:
• Comment your code intelligently.
• Indent your code properly.
• Use meaningful variable names.
• Use meaningful prompt lines/labels for input/output.
• Use meaningful project and C++ file name
Semaphores in Process Synchronization
Dining Philosopher Problem Using Semaphores
The Dining Philosopher Problem – The Dining Philosopher Problem states that K
philosophers seated around a circular table with one chopstick between each pair of
philosophers. There is one chopstick between each philosopher. A philosopher may eat if
he can pick up the two chopsticks adjacent to him. One chopstick may be picked up by any
one of its adjacent followers but not both.
Operating Systems
Semaphore Solution to Dining Philosopher –
Each philosopher is represented by the following pseudocode:
process P[i]
while true do
{ THINK;
PICKUP(CHOPSTICK[i], CHOPSTICK[i+1 mod 5]);
EAT;
PUTDOWN(CHOPSTICK[i], CHOPSTICK[i+1 mod 5])
}
There are three states of the philosopher: THINKING, HUNGRY, and EATING. Here
there are two semaphores: Mutex and a semaphore array for the philosophers. Mutex is
used such that no two philosophers may access the pickup or putdown at the same time.
The array is used to control the behavior of each philosopher. But, semaphores can result
in deadlock due to programming errors.
Solution of Dining Philosophers Problem
A solution of the Dining Philosophers Problem is to use a semaphore to represent a
chopstick. A chopstick can be picked up by executing a wait operation on the semaphore
and released by executing a signal semaphore.
Operating Systems
The structure of the chopstick is shown below −
semaphore chopstick [5];
Initially the elements of the chopstick are initialized to 1 as the chopsticks are on the table
and not picked up by a philosopher.
The structure of a random philosopher i is given as follows −
do {
wait( chopstick[i] );
wait( chopstick[ (i+1) % 5] );
. .
. EATING THE RICE
.
signal( chopstick[i] );
signal( chopstick[ (i+1) % 5] );
.
. THINKING
.
} while(1);
In the above structure, first wait operation is performed on chopstick[i] and chopstick[ (i+1) % 5].
This means that the philosopher i has picked up the chopsticks on his sides. Then the eating
function is performed.
After that, signal operation is performed on chopstick[i] and chopstick[ (i+1) % 5]. This means
that the philosopher i has eaten and put down the chopsticks on his sides. Then the philosopher
goes back to thinking.
Difficulty with the solution
The above solution makes sure that no two neighboring philosophers can eat at the same time.
But this solution can lead to a deadlock. This may happen if all the philosophers pick their left
chopstick simultaneously. Then none of them can eat and deadlock occurs.
Some of the ways to avoid deadlock are as follows −
 There should be at most four philosophers on the table.
 An even philosopher should pick the right chopstick and then the left chopstick while an
odd philosopher should pick the left chopstick and then the right chopstick.
Operating Systems
 A philosopher should only be allowed to pick their chopstick if both are available at the
same time.
Program for Dining Philosophers Problem in C++
#include<iostream>
#define n 4
using namespace std;
int compltedPhilo = 0,i;
struct fork{
int taken;
}ForkAvil[n];
struct philosp{
int left;
int right;
}Philostatus[n];
void goForDinner(int philID){ //same like threads concept here cases implemented
if(Philostatus[philID].left==10 && Philostatus[philID].right==10)
cout<<"Philosopher "<<philID+1<<" completed his dinnern";
//if already completed dinner
else if(Philostatus[philID].left==1 && Philostatus[philID].right==1){
//if just taken two forks
cout<<"Philosopher "<<philID+1<<" completed his dinnern";
Operating Systems
Philostatus[philID].left = Philostatus[philID].right = 10; //remembering that he
completed dinner by assigning value 10
int otherFork = philID-1;
if(otherFork== -1)
otherFork=(n-1);
ForkAvil[philID].taken = ForkAvil[otherFork].taken = 0; //releasing forks
cout<<"Philosopher "<<philID+1<<" released fork "<<philID+1<<" and fork
"<<otherFork+1<<"n";
compltedPhilo++;
}
else if(Philostatus[philID].left==1 && Philostatus[philID].right==0){ //left already
taken, trying for right fork
if(philID==(n-1)){
if(ForkAvil[philID].taken==0){ //KEY POINT OF THIS PROBLEM, THAT
LAST PHILOSOPHER TRYING IN reverse DIRECTION
ForkAvil[philID].taken = Philostatus[philID].right = 1;
cout<<"Fork "<<philID+1<<" taken by philosopher "<<philID+1<<"n";
}else{
cout<<"Philosopher "<<philID+1<<" is waiting for fork
"<<philID+1<<"n";
}
}else{ //except last philosopher case
int dupphilID = philID;
philID-=1;
Operating Systems
if(philID== -1)
philID=(n-1);
if(ForkAvil[philID].taken == 0){
ForkAvil[philID].taken = Philostatus[dupphilID].right = 1;
cout<<"Fork "<<philID+1<<" taken by Philosopher
"<<dupphilID+1<<"n";
}else{
cout<<"Philosopher "<<dupphilID+1<<" is waiting for Fork
"<<philID+1<<"n";
}
}
}
else if(Philostatus[philID].left==0){ //nothing taken yet
if(philID==(n-1)){
if(ForkAvil[philID-1].taken==0){ //KEY POINT OF THIS PROBLEM,
THAT LAST PHILOSOPHER TRYING IN reverse DIRECTION
ForkAvil[philID-1].taken = Philostatus[philID].left = 1;
cout<<"Fork "<<philID<<" taken by philosopher "<<philID+1<<"n";
}else{
cout<<"Philosopher "<<philID+1<<" is waiting for fork
"<<philID<<"n";
}
}else{ //except last philosopher case
if(ForkAvil[philID].taken == 0){
ForkAvil[philID].taken = Philostatus[philID].left = 1;
Operating Systems
cout<<"Fork "<<philID+1<<" taken by Philosopher "<<philID+1<<"n";
}else{
cout<<"Philosopher "<<philID+1<<" is waiting for Fork
"<<philID+1<<"n";
}
}
}else{}
}
int main(){
for(i=0;i<n;i++)
ForkAvil[i].taken=Philostatus[i].left=Philostatus[i].right=0;
while(compltedPhilo<n){
/* Observe here carefully, while loop will run until all philosophers complete
dinner
Actually problem of deadlock occur only thy try to take at same time
This for loop will say that they are trying at same time. And remaining status
will print by go for dinner function
*/
for(i=0;i<n;i++)
goForDinner(i);
cout<<"nTill now num of philosophers completed dinner are
"<<compltedPhilo<<"nn";
}
return 0;
Operating Systems
#include<iostream>
#define n 4
using namespace std;
int compltedPhilo = 0,i;
struct fork{
int taken;
}ForkAvil[n];
struct philosp{
int left;
int right;
}Philostatus[n];
void goForDinner(int philID){ //same like threads concept here cases implemented
if(Philostatus[philID].left==10 && Philostatus[philID].right==10)
cout<<"Philosopher "<<philID+1<<" completed his dinnern";
//if already completed dinner
else if(Philostatus[philID].left==1 && Philostatus[philID].right==1){
//if just taken two forks
cout<<"Philosopher "<<philID+1<<" completed his dinnern";
Operating Systems
Philostatus[philID].left = Philostatus[philID].right = 10; //remembering that he
completed dinner by assigning value 10
int otherFork = philID-1;
if(otherFork== -1)
otherFork=(n-1);
ForkAvil[philID].taken = ForkAvil[otherFork].taken = 0; //releasing forks
cout<<"Philosopher "<<philID+1<<" released fork "<<philID+1<<" and fork
"<<otherFork+1<<"n";
compltedPhilo++;
}
else if(Philostatus[philID].left==1 && Philostatus[philID].right==0){ //left already
taken, trying for right fork
if(philID==(n-1)){
if(ForkAvil[philID].taken==0){ //KEY POINT OF THIS PROBLEM, THAT
LAST PHILOSOPHER TRYING IN reverse DIRECTION
ForkAvil[philID].taken = Philostatus[philID].right = 1;
cout<<"Fork "<<philID+1<<" taken by philosopher "<<philID+1<<"n";
}else{
cout<<"Philosopher "<<philID+1<<" is waiting for fork
"<<philID+1<<"n";
}
}else{ //except last philosopher case
int dupphilID = philID;
philID-=1;
Operating Systems
if(philID== -1)
philID=(n-1);
if(ForkAvil[philID].taken == 0){
ForkAvil[philID].taken = Philostatus[dupphilID].right = 1;
cout<<"Fork "<<philID+1<<" taken by Philosopher
"<<dupphilID+1<<"n";
}else{
cout<<"Philosopher "<<dupphilID+1<<" is waiting for Fork
"<<philID+1<<"n";
}
}
}
else if(Philostatus[philID].left==0){ //nothing taken yet
if(philID==(n-1)){
if(ForkAvil[philID-1].taken==0){ //KEY POINT OF THIS PROBLEM,
THAT LAST PHILOSOPHER TRYING IN reverse DIRECTION
ForkAvil[philID-1].taken = Philostatus[philID].left = 1;
cout<<"Fork "<<philID<<" taken by philosopher "<<philID+1<<"n";
}else{
cout<<"Philosopher "<<philID+1<<" is waiting for fork
"<<philID<<"n";
}
}else{ //except last philosopher case
if(ForkAvil[philID].taken == 0){
ForkAvil[philID].taken = Philostatus[philID].left = 1;
cout<<"Fork "<<philID+1<<" taken by Philosopher "<<philID+1<<"n";
Operating Systems
}else{
cout<<"Philosopher "<<philID+1<<" is waiting for Fork
"<<philID+1<<"n";
}
}
}else{}
}
int main(){
for(i=0;i<n;i++)
ForkAvil[i].taken=Philostatus[i].left=Philostatus[i].right=0;
while(compltedPhilo<n){
/* Observe here carefully, while loop will run until all philosophers complete dinner
Actually problem of deadlock occur only thy try to take at same time
This for loop will say that they are trying at same time. And remaining status will print by
go for dinner function
*/
for(i=0;i<n;i++)
goForDinner(i);
cout<<"nTill now num of philosophers completed dinner are "<<compltedPhilo<<"nn";
}
return 0;
}
Operating Systems
Task: Write a program which implements Dining Philosophers problem and solution.
Code:
OUTPUTS:
Operating Systems
Lab Grading Sheet :
Task
Max
Marks
Obtained
Marks
Comments(if any)
1. 20
Total 20 Signature
Note : Attempt all tasks and get them checked by your Lab. Instructor

OS-Lab journal 10.pdf

  • 1.
    Bahria University, LahoreCampus Department of Computer Sciences Lab Journal 10 (Spring 2022) Course: Operating Systems Date: Course Code: CSL -320 Max Marks: 20 Faculty’s Name: Ms. Nighat Usman Name: Abdullah Arshad________________________________ Enroll No: 03-134201-030 _______________________ Objective(s): Introduction to Dining Philosophers and Deadlock Charaterization Compiler: Ubuntu, Terminal, Nano, G++ Important Note: • Comment your code intelligently. • Indent your code properly. • Use meaningful variable names. • Use meaningful prompt lines/labels for input/output. • Use meaningful project and C++ file name Semaphores in Process Synchronization Dining Philosopher Problem Using Semaphores The Dining Philosopher Problem – The Dining Philosopher Problem states that K philosophers seated around a circular table with one chopstick between each pair of philosophers. There is one chopstick between each philosopher. A philosopher may eat if he can pick up the two chopsticks adjacent to him. One chopstick may be picked up by any one of its adjacent followers but not both.
  • 2.
    Operating Systems Semaphore Solutionto Dining Philosopher – Each philosopher is represented by the following pseudocode: process P[i] while true do { THINK; PICKUP(CHOPSTICK[i], CHOPSTICK[i+1 mod 5]); EAT; PUTDOWN(CHOPSTICK[i], CHOPSTICK[i+1 mod 5]) } There are three states of the philosopher: THINKING, HUNGRY, and EATING. Here there are two semaphores: Mutex and a semaphore array for the philosophers. Mutex is used such that no two philosophers may access the pickup or putdown at the same time. The array is used to control the behavior of each philosopher. But, semaphores can result in deadlock due to programming errors. Solution of Dining Philosophers Problem A solution of the Dining Philosophers Problem is to use a semaphore to represent a chopstick. A chopstick can be picked up by executing a wait operation on the semaphore and released by executing a signal semaphore.
  • 3.
    Operating Systems The structureof the chopstick is shown below − semaphore chopstick [5]; Initially the elements of the chopstick are initialized to 1 as the chopsticks are on the table and not picked up by a philosopher. The structure of a random philosopher i is given as follows − do { wait( chopstick[i] ); wait( chopstick[ (i+1) % 5] ); . . . EATING THE RICE . signal( chopstick[i] ); signal( chopstick[ (i+1) % 5] ); . . THINKING . } while(1); In the above structure, first wait operation is performed on chopstick[i] and chopstick[ (i+1) % 5]. This means that the philosopher i has picked up the chopsticks on his sides. Then the eating function is performed. After that, signal operation is performed on chopstick[i] and chopstick[ (i+1) % 5]. This means that the philosopher i has eaten and put down the chopsticks on his sides. Then the philosopher goes back to thinking. Difficulty with the solution The above solution makes sure that no two neighboring philosophers can eat at the same time. But this solution can lead to a deadlock. This may happen if all the philosophers pick their left chopstick simultaneously. Then none of them can eat and deadlock occurs. Some of the ways to avoid deadlock are as follows −  There should be at most four philosophers on the table.  An even philosopher should pick the right chopstick and then the left chopstick while an odd philosopher should pick the left chopstick and then the right chopstick.
  • 4.
    Operating Systems  Aphilosopher should only be allowed to pick their chopstick if both are available at the same time. Program for Dining Philosophers Problem in C++ #include<iostream> #define n 4 using namespace std; int compltedPhilo = 0,i; struct fork{ int taken; }ForkAvil[n]; struct philosp{ int left; int right; }Philostatus[n]; void goForDinner(int philID){ //same like threads concept here cases implemented if(Philostatus[philID].left==10 && Philostatus[philID].right==10) cout<<"Philosopher "<<philID+1<<" completed his dinnern"; //if already completed dinner else if(Philostatus[philID].left==1 && Philostatus[philID].right==1){ //if just taken two forks cout<<"Philosopher "<<philID+1<<" completed his dinnern";
  • 5.
    Operating Systems Philostatus[philID].left =Philostatus[philID].right = 10; //remembering that he completed dinner by assigning value 10 int otherFork = philID-1; if(otherFork== -1) otherFork=(n-1); ForkAvil[philID].taken = ForkAvil[otherFork].taken = 0; //releasing forks cout<<"Philosopher "<<philID+1<<" released fork "<<philID+1<<" and fork "<<otherFork+1<<"n"; compltedPhilo++; } else if(Philostatus[philID].left==1 && Philostatus[philID].right==0){ //left already taken, trying for right fork if(philID==(n-1)){ if(ForkAvil[philID].taken==0){ //KEY POINT OF THIS PROBLEM, THAT LAST PHILOSOPHER TRYING IN reverse DIRECTION ForkAvil[philID].taken = Philostatus[philID].right = 1; cout<<"Fork "<<philID+1<<" taken by philosopher "<<philID+1<<"n"; }else{ cout<<"Philosopher "<<philID+1<<" is waiting for fork "<<philID+1<<"n"; } }else{ //except last philosopher case int dupphilID = philID; philID-=1;
  • 6.
    Operating Systems if(philID== -1) philID=(n-1); if(ForkAvil[philID].taken== 0){ ForkAvil[philID].taken = Philostatus[dupphilID].right = 1; cout<<"Fork "<<philID+1<<" taken by Philosopher "<<dupphilID+1<<"n"; }else{ cout<<"Philosopher "<<dupphilID+1<<" is waiting for Fork "<<philID+1<<"n"; } } } else if(Philostatus[philID].left==0){ //nothing taken yet if(philID==(n-1)){ if(ForkAvil[philID-1].taken==0){ //KEY POINT OF THIS PROBLEM, THAT LAST PHILOSOPHER TRYING IN reverse DIRECTION ForkAvil[philID-1].taken = Philostatus[philID].left = 1; cout<<"Fork "<<philID<<" taken by philosopher "<<philID+1<<"n"; }else{ cout<<"Philosopher "<<philID+1<<" is waiting for fork "<<philID<<"n"; } }else{ //except last philosopher case if(ForkAvil[philID].taken == 0){ ForkAvil[philID].taken = Philostatus[philID].left = 1;
  • 7.
    Operating Systems cout<<"Fork "<<philID+1<<"taken by Philosopher "<<philID+1<<"n"; }else{ cout<<"Philosopher "<<philID+1<<" is waiting for Fork "<<philID+1<<"n"; } } }else{} } int main(){ for(i=0;i<n;i++) ForkAvil[i].taken=Philostatus[i].left=Philostatus[i].right=0; while(compltedPhilo<n){ /* Observe here carefully, while loop will run until all philosophers complete dinner Actually problem of deadlock occur only thy try to take at same time This for loop will say that they are trying at same time. And remaining status will print by go for dinner function */ for(i=0;i<n;i++) goForDinner(i); cout<<"nTill now num of philosophers completed dinner are "<<compltedPhilo<<"nn"; } return 0;
  • 8.
    Operating Systems #include<iostream> #define n4 using namespace std; int compltedPhilo = 0,i; struct fork{ int taken; }ForkAvil[n]; struct philosp{ int left; int right; }Philostatus[n]; void goForDinner(int philID){ //same like threads concept here cases implemented if(Philostatus[philID].left==10 && Philostatus[philID].right==10) cout<<"Philosopher "<<philID+1<<" completed his dinnern"; //if already completed dinner else if(Philostatus[philID].left==1 && Philostatus[philID].right==1){ //if just taken two forks cout<<"Philosopher "<<philID+1<<" completed his dinnern";
  • 9.
    Operating Systems Philostatus[philID].left =Philostatus[philID].right = 10; //remembering that he completed dinner by assigning value 10 int otherFork = philID-1; if(otherFork== -1) otherFork=(n-1); ForkAvil[philID].taken = ForkAvil[otherFork].taken = 0; //releasing forks cout<<"Philosopher "<<philID+1<<" released fork "<<philID+1<<" and fork "<<otherFork+1<<"n"; compltedPhilo++; } else if(Philostatus[philID].left==1 && Philostatus[philID].right==0){ //left already taken, trying for right fork if(philID==(n-1)){ if(ForkAvil[philID].taken==0){ //KEY POINT OF THIS PROBLEM, THAT LAST PHILOSOPHER TRYING IN reverse DIRECTION ForkAvil[philID].taken = Philostatus[philID].right = 1; cout<<"Fork "<<philID+1<<" taken by philosopher "<<philID+1<<"n"; }else{ cout<<"Philosopher "<<philID+1<<" is waiting for fork "<<philID+1<<"n"; } }else{ //except last philosopher case int dupphilID = philID; philID-=1;
  • 10.
    Operating Systems if(philID== -1) philID=(n-1); if(ForkAvil[philID].taken== 0){ ForkAvil[philID].taken = Philostatus[dupphilID].right = 1; cout<<"Fork "<<philID+1<<" taken by Philosopher "<<dupphilID+1<<"n"; }else{ cout<<"Philosopher "<<dupphilID+1<<" is waiting for Fork "<<philID+1<<"n"; } } } else if(Philostatus[philID].left==0){ //nothing taken yet if(philID==(n-1)){ if(ForkAvil[philID-1].taken==0){ //KEY POINT OF THIS PROBLEM, THAT LAST PHILOSOPHER TRYING IN reverse DIRECTION ForkAvil[philID-1].taken = Philostatus[philID].left = 1; cout<<"Fork "<<philID<<" taken by philosopher "<<philID+1<<"n"; }else{ cout<<"Philosopher "<<philID+1<<" is waiting for fork "<<philID<<"n"; } }else{ //except last philosopher case if(ForkAvil[philID].taken == 0){ ForkAvil[philID].taken = Philostatus[philID].left = 1; cout<<"Fork "<<philID+1<<" taken by Philosopher "<<philID+1<<"n";
  • 11.
    Operating Systems }else{ cout<<"Philosopher "<<philID+1<<"is waiting for Fork "<<philID+1<<"n"; } } }else{} } int main(){ for(i=0;i<n;i++) ForkAvil[i].taken=Philostatus[i].left=Philostatus[i].right=0; while(compltedPhilo<n){ /* Observe here carefully, while loop will run until all philosophers complete dinner Actually problem of deadlock occur only thy try to take at same time This for loop will say that they are trying at same time. And remaining status will print by go for dinner function */ for(i=0;i<n;i++) goForDinner(i); cout<<"nTill now num of philosophers completed dinner are "<<compltedPhilo<<"nn"; } return 0; }
  • 12.
    Operating Systems Task: Writea program which implements Dining Philosophers problem and solution. Code: OUTPUTS:
  • 13.
    Operating Systems Lab GradingSheet : Task Max Marks Obtained Marks Comments(if any) 1. 20 Total 20 Signature Note : Attempt all tasks and get them checked by your Lab. Instructor