Dining philosopher mutex_2

Post on 13-Apr-2017

262 Views

Category:

Education

0 Downloads

Preview:

Click to see full reader

Transcript

Dining Philosopher ProblemDining Philosopher Problem

ByByCHITRAKANT BANCHHORCHITRAKANT BANCHHOR

IT,IT, MITCOEMITCOE,, PunePune

ByByCHITRAKANT BANCHHORCHITRAKANT BANCHHOR

IT,IT, MITCOEMITCOE,, PunePune

ReferencesReferences

•• Operating system concepts, 6th edition byOperating system concepts, 6th edition by Silberschatz A, Galvin andSilberschatz A, Galvin andGagne.Gagne.

•• Operating Systems, 4th edition by William StallingsOperating Systems, 4th edition by William Stallings

•• Operating Systems ByOperating Systems By DeitelDeitel

2

•• Operating system concepts, 6th edition byOperating system concepts, 6th edition by Silberschatz A, Galvin andSilberschatz A, Galvin andGagne.Gagne.

•• Operating Systems, 4th edition by William StallingsOperating Systems, 4th edition by William Stallings

•• Operating Systems ByOperating Systems By DeitelDeitel

IntroductionIntroduction

E.W.E.W. DijkstraDijkstra: The dining philosopher problem was first: The dining philosopher problem was firstmade up bymade up by DijkstraDijkstra

•• SignificanceSignificance::

•• Designing deadlock and starvationDesigning deadlock and starvation--free solutions to the complex problems infree solutions to the complex problems incomputer science.computer science.

The ProblemThe Problem

0

14

100

1

23

4

4

3

2

1

2 3

4

•• Think and Eat statesThink and Eat states::

A philosopher’s life is simplified into two states:A philosopher’s life is simplified into two states: think and eatthink and eat..

Every philosopher indefinitely repeats these states.Every philosopher indefinitely repeats these states.

•• Assumptions:Assumptions:

A philosopher cannot continuouslyA philosopher cannot continuously eateat oror thinkthink..

A philosopher must change his or her state every once in a while.A philosopher must change his or her state every once in a while.

•• Think and Eat statesThink and Eat states::

A philosopher’s life is simplified into two states:A philosopher’s life is simplified into two states: think and eatthink and eat..

Every philosopher indefinitely repeats these states.Every philosopher indefinitely repeats these states.

•• Assumptions:Assumptions:

A philosopher cannot continuouslyA philosopher cannot continuously eateat oror thinkthink..

A philosopher must change his or her state every once in a while.A philosopher must change his or her state every once in a while.

0

14

1 0

Left and Right forks:Left and Right forks: A philosopher must seize the two forks.A philosopher must seize the two forks.

RulesRules

23

4

4

3

2

Complicated case:Complicated case: The case becomes complicated when the rule thatThe case becomes complicated when the rule thatevery philosopher has to use two forks to eat rice must be observed toevery philosopher has to use two forks to eat rice must be observed toarrive at an acceptable solution.arrive at an acceptable solution.

Shared resourcesShared resources

A computer processA computer process

Computer system analogyComputer system analogy

Synchronization not required:Synchronization not required:

When there are enough forks, the processes are independent and there isWhen there are enough forks, the processes are independent and there isno need for synchronizationno need for synchronization

0

1

23

4

1 0

4

3

2

0

1

2 3

4

1.1. Plates are numbered in a counter clockwise direction fromPlates are numbered in a counter clockwise direction from 0 to 40 to 4

2.2. PhilosopherPhilosopher ii,, ii = 0 , 1 , … , and 4= 0 , 1 , … , and 4, is sitting at the table so as to use plate number, is sitting at the table so as to use plate number ii

3.3. ForksForks are numbered so that fork numberare numbered so that fork number ii,, ii = 0, 1 , … , 4 , is next to= 0, 1 , … , 4 , is next to philosopherphilosopher ii atathis or her left sidehis or her left side

Dining Philosopher Problem solutionDining Philosopher Problem solution

First AttemptFirst Attempt

1. Start eating: If two forks are successfully grabbed by philosophersthen they start eating.

2. Puts down a fork: The philosopher puts down the forks one at atime.

3. Grab left fork: It does not really matter which fork is taken first by aphilosopher, so, we will assume the fork on his left hand side isgrabbed first.

1. Start eating: If two forks are successfully grabbed by philosophersthen they start eating.

2. Puts down a fork: The philosopher puts down the forks one at atime.

3. Grab left fork: It does not really matter which fork is taken first by aphilosopher, so, we will assume the fork on his left hand side isgrabbed first.

Assumed Primitive operationsAssumed Primitive operations

1. grab_fork( int fork_no ) : To grab the nominated fork.

2. put _fork ( int fork_no ) : To put down the nominated fork.

Proper care is taken, in writing these procedures, to avoidProper care is taken, in writing these procedures, to avoidrace conditions when grabbing or putting down a fork.race conditions when grabbing or putting down a fork.

void philosopher ( int i ) /* i = 0, 1, …, n-1 is the philosopher number */{

while (1) { /* Do this loop forever */

Think; /* Think for a while */

grab_fork(i); /* Grab left fork */

grab_fork((i+1)%n); /* Grab right fork */

Eat; /* Eat as you like */

put_fork(i); /* Put left fork */

put_fork((i+1)%n); /* Put right fork */}

}

void philosopher ( int i ) /* i = 0, 1, …, n-1 is the philosopher number */{

while (1) { /* Do this loop forever */

Think; /* Think for a while */

grab_fork(i); /* Grab left fork */

grab_fork((i+1)%n); /* Grab right fork */

Eat; /* Eat as you like */

put_fork(i); /* Put left fork */

put_fork((i+1)%n); /* Put right fork */}

}

This procedure is executed by each philosopher.This procedure is executed by each philosopher.

TheThe grab_forkgrab_fork andand put_forkput_fork procedures are assumed to beprocedures are assumed to be race freerace free procedures.procedures.

ScenarioScenario –– 1:1:

• Each philosopher has taken left fork: All philosopher processes get to thepoint where each one has taken the left fork

• Now each one tries to take the right fork, executing grab_fork((i+1)%n).

0

Deadlock:Deadlock:

1.1. In such circumstances, no fork is available and all philosophers will enter aIn such circumstances, no fork is available and all philosophers will enter await state.wait state.

2.2. This will result in aThis will result in a circularcircular--wait conditionwait condition which in turn indicates awhich in turn indicates a deadlockdeadlock..

1

23

4

1 0

4

3

2

Processes synchronized: ( 0 and 3 and 2 and 4 )2 and 4 )

Processes 0 and 3 and 2 and 42 and 4 are so synchronizedsynchronized that:

Whenever 0 and 30 and 3 are eating 2 and 42 and 4 are thinking

and as soon as 0 and 30 and 3 put down their forks 2 and 42 and 4 grab them immediately.

Also, whenever 2 and 42 and 4 put down their forks 0 and 30 and 3 grab them immediately.

ScenarioScenario –– 2:2:

Processes synchronized: ( 0 and 3 and 2 and 4 )2 and 4 )

Processes 0 and 3 and 2 and 42 and 4 are so synchronizedsynchronized that:

Whenever 0 and 30 and 3 are eating 2 and 42 and 4 are thinking

and as soon as 0 and 30 and 3 put down their forks 2 and 42 and 4 grab them immediately.

Also, whenever 2 and 42 and 4 put down their forks 0 and 30 and 3 grab them immediately.

00

1

22 33

44

1 0

4

3

2

Starvation:Starvation:

001

22 33

44

1 0

4

3

2

Philosopher 1 will starve to deathPhilosopher 1 will starve to death :: If this cycle repeats forever,If this cycle repeats forever, Philosopher 1Philosopher 1will starve to death and, thus, a starvation state is possible.will starve to death and, thus, a starvation state is possible.

Second AttemptSecond Attempt

In this attempt, we will focus on removing the possibility of deadlockfrom the Attempt 1’s solution.

Avoid Hold & Wait condition:Avoid Hold & Wait condition:

Philosopher(i) :if ( gets both forks || does not get any forks ){

Possibility of hold and wait is removed}

New Procedure :New Procedure :

grab_forksgrab_forks( int( int philosopher_nophilosopher_no ))

1. Suppose we have prepared this as a new race-free procedure.

2. This is used to grab both forks at one time, whenever possible.

1. Suppose we have prepared this as a new race-free procedure.

2. This is used to grab both forks at one time, whenever possible.

void philosopher ( int i ) /* i = 0, 1, …, n-1 is the philosopher number */{

while (1) { /* Do this loop forever */

Think; /* Think for a while */

grab_forks(i); /* Grab both forks */

Eat; /* Eat as you like */

put_fork(i); /* Put left fork down*/

put_fork((i+1)%n); /* Put right fork down*/}

}

void philosopher ( int i ) /* i = 0, 1, …, n-1 is the philosopher number */{

while (1) { /* Do this loop forever */

Think; /* Think for a while */

grab_forks(i); /* Grab both forks */

Eat; /* Eat as you like */

put_fork(i); /* Put left fork down*/

put_fork((i+1)%n); /* Put right fork down*/}

}

Deadlock freeDeadlock free:: This algorithm removes the possibility of a holdThis algorithm removes the possibility of a hold--andand--waitwaitsituation. Hence, it is deadlock free.situation. Hence, it is deadlock free.

StarvationStarvation:: IfIf put_forkput_fork((ii)) simply puts a fork down, the starvation possibilitysimply puts a fork down, the starvation possibilitypersists, similar to Attempt 1.persists, similar to Attempt 1.

The Dining Philosopher’s solutionThe Dining Philosopher’s solutionusing Binary semaphore &using Binary semaphore & mutexmutexThe Dining Philosopher’s solutionThe Dining Philosopher’s solutionusing Binary semaphore &using Binary semaphore & mutexmutex

1. down ( &mutex):

A philosopher has to execute this operation first to access any fork.

2. up ( &mutex ):

As soon as the access is completed, this operation is executed.

Variables and conditions usedVariables and conditions used

1. down ( &mutex):

A philosopher has to execute this operation first to access any fork.

2. up ( &mutex ):

As soon as the access is completed, this operation is executed.

down ( &mutex )

up ( &mutex )

access_any_fork( )

3. Mutex:

Mutex is a binary variable semaphore.

Initial value set to 1: to allow the first attempt to access to be successful.

Use of up(&mutex) and down(&mutex):

The proper use of down and up ensures that no more than one philosopher

will try to simultaneously grab_forks or put_forks.

3. Mutex:

Mutex is a binary variable semaphore.

Initial value set to 1: to allow the first attempt to access to be successful.

Use of up(&mutex) and down(&mutex):

The proper use of down and up ensures that no more than one philosopher

will try to simultaneously grab_forks or put_forks.

4. n : Number of philosophers.

5. semaphore available [ n ] :

an array of n semaphores.

This is used to handle the situation where : A philosopher mayhave to wait because either both forks or next to him are being used bya neighbor(s).

5. semaphore available [ n ] :

an array of n semaphores.

This is used to handle the situation where : A philosopher mayhave to wait because either both forks or next to him are being used bya neighbor(s).

if ( available ( forks(if ( available ( forks( ii ) ) == false || available () ) == false || available ( right_forkright_fork (( ii ) == false ) ) {) == false ) ) {wait ( Philosopher[wait ( Philosopher[ ii ] );] );

}}

Philosopher ( i ) wants to eat:

if ( available ( left_fork_( philosopher(i) ) && right_fork_( philosopher(i) ) ) == true ){

start_eating( Philosopher( i ) );}else {

wait _on_signal ( Philosopher ( i ) for corresponding semaphore );

/* when receives a signal from the neighbor then start eating */if ( receive ( signal_from ( neighbor (i) ) ) == true ) {

start_eating( Philosopher( i ) );}

}

workingworking

Philosopher ( i ) wants to eat:

if ( available ( left_fork_( philosopher(i) ) && right_fork_( philosopher(i) ) ) == true ){

start_eating( Philosopher( i ) );}else {

wait _on_signal ( Philosopher ( i ) for corresponding semaphore );

/* when receives a signal from the neighbor then start eating */if ( receive ( signal_from ( neighbor (i) ) ) == true ) {

start_eating( Philosopher( i ) );}

}

Neighbor ( Philosopher ( i ) ) signal ( to Philosopher( i ) ) when puts down forks

001

22 33

441 0

4

3

2

if ( available ( left_fork_( philosopher(4) ) && right_fork_( philosopher(4) ) ) == true ){

start_eating( Philosopher( 4 ) );}

001

22 33

441 0

4

3

2

Semaphore 0

Semaphore 3

else {wait _on_signal ( Philosopher ( 4 ) for corresponding semaphore );

/* when receives a signal from the neighbor(s) then start eating *//* when receives a signal from the neighbor(s) then start eating */if ( receive (if ( receive ( signal_fromsignal_from ( neighbor (( neighbor (ii) ) ) == true ) {) ) ) == true ) {

start_eatingstart_eating( Philosopher(( Philosopher( ii ) );) );}}

}

001

22 33

441 0

4

3

2

Semaphore 0

Semaphore 4

else {wait _wait _on_signalon_signal ( Philosopher (( Philosopher ( ii ) for corresponding semaphore );) for corresponding semaphore );

/* when receives a signal from the neighbor(s) then start eating */if ( receive ( signal_from ( neighbor (4) ) ) == true ) {

start_eating( Philosopher( i ) );}

}

Global variablesGlobal variables

#define n 5#define n 5

semaphoresemaphore mutexmutex = 1 ;= 1 ;

semaphore available[n]={0}; // All elements of available are set to zerosemaphore available[n]={0}; // All elements of available are set to zero

intint forks [ n ] ;forks [ n ] ;

intint waiting [ n ] ; // Is the philosopher waiting?waiting [ n ] ; // Is the philosopher waiting?

#define n 5#define n 5

semaphoresemaphore mutexmutex = 1 ;= 1 ;

semaphore available[n]={0}; // All elements of available are set to zerosemaphore available[n]={0}; // All elements of available are set to zero

intint forks [ n ] ;forks [ n ] ;

intint waiting [ n ] ; // Is the philosopher waiting?waiting [ n ] ; // Is the philosopher waiting?

Main functionMain function

intint main()main(){{

for (for ( ii = 0;= 0; ii < n ;< n ; ii++ ) {++ ) {forks [forks [ ii ] =] = ii ;;

}}

for (for ( ii = 0;= 0; ii < n;< n; ii++ ) {++ ) {philosopher (philosopher ( ii ););

}}return 0;return 0;}}

intint main()main(){{

for (for ( ii = 0;= 0; ii < n ;< n ; ii++ ) {++ ) {forks [forks [ ii ] =] = ii ;;

}}

for (for ( ii = 0;= 0; ii < n;< n; ii++ ) {++ ) {philosopher (philosopher ( ii ););

}}return 0;return 0;}}

Philosopher functionPhilosopher function/*/* ii = 0,1,2..,n= 0,1,2..,n--1 is the philosopher number */1 is the philosopher number */void philosopher (void philosopher ( intint ii )){{

while ( 1 ) {while ( 1 ) {

start_thinkingstart_thinking;; /* Think for a while *//* Think for a while */

grab_forksgrab_forks(( ii );); /* Grab both forks *//* Grab both forks */

start_eatingstart_eating;; /* Eat as you like *//* Eat as you like */

put_left_forkput_left_fork(( ii );); /* Put left fork down *//* Put left fork down */

put_right_forkput_right_fork(( ii );); /* Put right fork down *//* Put right fork down */}}

}}

/*/* ii = 0,1,2..,n= 0,1,2..,n--1 is the philosopher number */1 is the philosopher number */void philosopher (void philosopher ( intint ii )){{

while ( 1 ) {while ( 1 ) {

start_thinkingstart_thinking;; /* Think for a while *//* Think for a while */

grab_forksgrab_forks(( ii );); /* Grab both forks *//* Grab both forks */

start_eatingstart_eating;; /* Eat as you like *//* Eat as you like */

put_left_forkput_left_fork(( ii );); /* Put left fork down *//* Put left fork down */

put_right_forkput_right_fork(( ii );); /* Put right fork down *//* Put right fork down */}}

}}

Grab forks functionGrab forks functionvoid grab_forks ( int i ){

int both_forks_available = 0; // To be set to one if both forks are available

down ( &mutex ); // Forks are protected

waiting[ i ] = 0; // To be set to one if philosopher has to wait

// If both forks are availableif ( fork[ i ] && fork( [ i + 1 ] % n ) {

fork[ i ] = 0; // Grab left forkfork[ ( i + 1 ) % n ] = 0; // Grab right forkboth_forks_available = 1;

}else {

waiting[ i ] = 1; // The philosopher has to wait}

up ( &mutex ); // Leave forks critical regionif ( both_forks_available != 1 )

down (&available[i]); // The philosopher has to await forks}

void grab_forks ( int i ){

int both_forks_available = 0; // To be set to one if both forks are available

down ( &mutex ); // Forks are protected

waiting[ i ] = 0; // To be set to one if philosopher has to wait

// If both forks are availableif ( fork[ i ] && fork( [ i + 1 ] % n ) {

fork[ i ] = 0; // Grab left forkfork[ ( i + 1 ) % n ] = 0; // Grab right forkboth_forks_available = 1;

}else {

waiting[ i ] = 1; // The philosopher has to wait}

up ( &mutex ); // Leave forks critical regionif ( both_forks_available != 1 )

down (&available[i]); // The philosopher has to await forks}

001

22 33

441 0

4

3

2

down ( &mutex ); // Forks are protected

waiting[ 4 ] = 0; // To be set to one if philosopher has to wait

// If both forks are availableif ( fork[ 4 ] && fork( [ 4 + 1 ] % 5 ) {

fork[ 4 ] = 0; // Grab left forkfork[ ( 4 + 1 ) % 5 ] = 0; // Grab right forkboth_forks_available = 1;

}else {else {

waiting[ 4 ] = 1; // The philosopher has to waitwaiting[ 4 ] = 1; // The philosopher has to wait}}

up ( &mutex ); // Leave forks critical region

down ( &mutex ); // Forks are protected

waiting[ 4 ] = 0; // To be set to one if philosopher has to wait

// If both forks are availableif ( fork[ 4 ] && fork( [ 4 + 1 ] % 5 ) {

fork[ 4 ] = 0; // Grab left forkfork[ ( 4 + 1 ) % 5 ] = 0; // Grab right forkboth_forks_available = 1;

}else {else {

waiting[ 4 ] = 1; // The philosopher has to waitwaiting[ 4 ] = 1; // The philosopher has to wait}}

up ( &mutex ); // Leave forks critical region

001

22 33

441 0

4

3

2

Put_left_forkPut_left_fork functionfunction

void put_left_fork ( int i ){

down ( &mutex ) // Forks are protectedif ( waiting[ ( i – 1 ) % n ] && fork[ ( i – 1 ) % n ] ){

fork[ ( i – 1 ) % n ] = 0 ;waiting[ ( i – 1 )% n ] = 0;up(&available[ ( i – 1 ) % n ] );

}else

fork[ i ] = 1; // Return this forkup (&mutex); // Leave forks critical region

}

void put_left_fork ( int i ){

down ( &mutex ) // Forks are protectedif ( waiting[ ( i – 1 ) % n ] && fork[ ( i – 1 ) % n ] ){

fork[ ( i – 1 ) % n ] = 0 ;waiting[ ( i – 1 )% n ] = 0;up(&available[ ( i – 1 ) % n ] );

}else

fork[ i ] = 1; // Return this forkup (&mutex); // Leave forks critical region

}

001

22 33

441 0

4

3

2

void put_left_fork ( 4 ){

down ( &mutex ) // Forks are protectedif ( waiting[ ( 4 – 1 ) % 5 ] && fork[ ( 4 – 1 ) % 5 ] ){

fork[ ( 4 – 1 ) % 5 ] = 0 ;waiting[ ( 4 – 1 )% 5 ] = 0;up(&available[ ( 4 – 1 ) % 5 ] );

}else

fork[ 4 ] = 1; // Return this forkup (&mutex); // Leave forks critical region

}

void put_left_fork ( 4 ){

down ( &mutex ) // Forks are protectedif ( waiting[ ( 4 – 1 ) % 5 ] && fork[ ( 4 – 1 ) % 5 ] ){

fork[ ( 4 – 1 ) % 5 ] = 0 ;waiting[ ( 4 – 1 )% 5 ] = 0;up(&available[ ( 4 – 1 ) % 5 ] );

}else

fork[ 4 ] = 1; // Return this forkup (&mutex); // Leave forks critical region

}

Put_right_forkPut_right_fork functionfunction

void put_right_fork ( int i ){

down ( &mutex ) // Forks are protectedif ( waiting [ ( i + 1 ) % n ] && fork [ ( i + 2 ) % n ] ){

fork[ ( i + 2 ) % n ] = 0;waiting [ ( i + 1 ) % n ] = 0;up ( &available [ ( i + 1 ) % n ) ;

}else {

fork [ ( i + 1 ) % n ] = 1; // Return this fork}

up (&mutex); // Leave forks critical region}

void put_right_fork ( int i ){

down ( &mutex ) // Forks are protectedif ( waiting [ ( i + 1 ) % n ] && fork [ ( i + 2 ) % n ] ){

fork[ ( i + 2 ) % n ] = 0;waiting [ ( i + 1 ) % n ] = 0;up ( &available [ ( i + 1 ) % n ) ;

}else {

fork [ ( i + 1 ) % n ] = 1; // Return this fork}

up (&mutex); // Leave forks critical region}

001

22 33

441 0

4

3

2

void put_right_fork ( 4 ){

down ( &mutex ) // Forks are protectedif ( waiting [ ( 4 + 1 ) % n ] && fork [ ( 4 + 2 ) % n ] ){

fork[ ( 4 + 2 ) % 5 ] = 0;waiting [ ( 4 + 1 ) % 5 ] = 0;up ( &available [ ( 4 + 1 ) % 5 ) ;

}else {

fork [ ( 4 + 1 ) % 5 ] = 1; // Return this fork}

up (&mutex); // Leave forks critical region}

void put_right_fork ( 4 ){

down ( &mutex ) // Forks are protectedif ( waiting [ ( 4 + 1 ) % n ] && fork [ ( 4 + 2 ) % n ] ){

fork[ ( 4 + 2 ) % 5 ] = 0;waiting [ ( 4 + 1 ) % 5 ] = 0;up ( &available [ ( 4 + 1 ) % 5 ) ;

}else {

fork [ ( 4 + 1 ) % 5 ] = 1; // Return this fork}

up (&mutex); // Leave forks critical region}

Deadlock and starvation freeDeadlock and starvation free

•• The final solution to the dining philosopher is deadlock andThe final solution to the dining philosopher is deadlock andstarvation free.starvation free.

•• The final solution to the dining philosopher is deadlock andThe final solution to the dining philosopher is deadlock andstarvation free.starvation free.

Deadlock freeDeadlock free

Grabbing both forks :Grabbing both forks :

Deadlock is prevented by grabbing both forks when available, at one time andDeadlock is prevented by grabbing both forks when available, at one time andpreventing a holdpreventing a hold--andand--wait conditionwait condition..

Grabbing both forks :Grabbing both forks :

Deadlock is prevented by grabbing both forks when available, at one time andDeadlock is prevented by grabbing both forks when available, at one time andpreventing a holdpreventing a hold--andand--wait conditionwait condition..

Starvation freeStarvation free•• The starvation freeness is guaranteed by the way the waitingThe starvation freeness is guaranteed by the way the waiting

neighbor(s) are alerted when a philosopher puts down her forks.neighbor(s) are alerted when a philosopher puts down her forks.

•• This is accomplished by checking whether or not both forks of theThis is accomplished by checking whether or not both forks of theneighboring philosophers are available whenever a philosopher putsneighboring philosophers are available whenever a philosopher putsdown forks.down forks.

•• The starvation freeness is guaranteed by the way the waitingThe starvation freeness is guaranteed by the way the waitingneighbor(s) are alerted when a philosopher puts down her forks.neighbor(s) are alerted when a philosopher puts down her forks.

•• This is accomplished by checking whether or not both forks of theThis is accomplished by checking whether or not both forks of theneighboring philosophers are available whenever a philosopher putsneighboring philosophers are available whenever a philosopher putsdown forks.down forks.

Thank You!Thank You!Thank You!Thank You!

41

top related