# PV operation questions

## the dining philosophers problem

### Problem Description:

Have n (n) ≥ \ge ≥ 3) philosophers sit around a round table, and each philosopher eats and thinks alternately. There is m(m) in the center of the round table ≥ \ge ≥ 1) bowl, with one chopstick between each two philosophers. Every philosopher must take a bowl and chopsticks on both sides before eating. After eating, put the bowl and chopsticks back in place and continue thinking. In order to make as many philosophers eat at the same time as possible and prevent deadlock, please use the P and V operations of semaphores [wait(), signal() operation] to describe the mutual exclusion and synchronization in the above process, and explain the meaning of semaphores and initial values used.

### Solution 1: limit the maximum number of people who can access resources

```semaphore capacity = n-1;		//Indicates that at most n-1 philosophers can compete for resources
semaphore bowl = m;				//bowl
semaphore chopsticks[n] = {1};	//n chopsticks,
for(int i = 0; i < n; i++)
chopsticks[i] = 1;			//The number of chopsticks on each side is 1

Process Philosopher()
{
while(true)
{
reflection

P(capacity);			//Up to n-1 people can access the resource
P(bowl)					//Application bowl
P(chopsticks[i]);		//Left hand chopsticks
P(chopsticks[(i+1)%n]	//Right hand chopsticks
Dry rice
V(bowl);
V(chopsticks[i]);
V(chopsticks[(i+1)%n];
V(capacity);

}
}
```

### Solution 1 Optimization

The number of bowls m can be used to limit the number of visitors, that is, the semaphore bowl not only acts as a resource, but also limits the number of visitors. It should be noted that the number of bowls must be less than n

```semaphore bowl；				//bowl
semaphore chopsticks[n] = {1};	//n chopsticks,
for(int i = 0; i < n; i++)
chopsticks[i] = 1;			//The number of chopsticks on each side is 1
bowl = min(m,n-1);				//Limit the maximum number of people accessing resources to n-1

Process Philosopher()
{
while(true)
{
reflection

P(bowl);				//Take a bowl
P(chopsticks[i]);		//Left hand chopsticks
P(chopsticks[(i+1)%n]	//Right hand chopsticks

Dry rice

V(chopsticks[i]);
V(chopsticks[(i+1)%n];
V(bowl);
}
}
```

Book Description: a philosopher is allowed to grab chopsticks only when both left and right chopsticks are available.

Personal understanding: in fact, this strategy is to "lock" the whole process of philosophers applying for resources, that is, when philosophers can only apply for resources mutually exclusive, it ensures that the first philosopher can apply for all resources.

```semaphore lock = 1;				//Semaphores used to mutually exclusive request resources
semaphore bowl = m；			//bowl
semaphore chopsticks[n] = {1};	//n chopsticks,
for(int i = 0; i < n; i++)
chopsticks[i] = 1;			//The number of chopsticks on each side is 1

Process Philosopher()
{
while(true)
{
reflection

P(lock);				//"Lock"
P(chopsticks[i]);		//Left hand chopsticks
P(chopsticks[(i+1)%n]	//Right hand chopsticks
P(bowl);				//Take a bowl
V(lock);

Dry rice

V(chopsticks[i]);
V(chopsticks[(i+1)%n];
V(bowl);
}
}
```

### Solution two optimization

In the previous solution, if the process scheduling occurs after the processes of philosophers other than the first philosopher execute the application, and after one cycle of concurrent execution, There will be a situation that only the first philosopher has the resources to eat in his hand (at worst), while other philosophers only have a chopstick in his left hand. This is consistent with the requirement of "Let as many philosophers eat at the same time" Inconsistent. Therefore, consider the following optimization. While locking, judge whether philosophers can apply for all resources. If they can, take them. Otherwise, they will not apply.

```int n = 10;                         //Number of chopsticks
int m = 10;                        //Number of bowls
semaphore lck = 1;					//Semaphore of resource
bool chopsticks[n];            		//The status of all chopsticks, false is not taken away
int bowls = 0;                     	//Number of bowls currently allocated
for(int i = 0; i < n; i++)
chopsticks[i] = false;			//Initialize all chopsticks as not taken away

Progress Philosopher(int i)			//Philosopher i
{
while (true)
{
//reflection

P(lck);		//Ensure that only one philosopher is trying to take it at the same time
if (!chopsticks[i] && !chopsticks[(i + 1) % n] && bowls < m)//Only when you can get all the resources can you apply
{
chopsticks[i] = true;           //Take the left chopsticks
chopsticks[(i + 1) % n] = true; //Take your right chopsticks
bowls++;                        //Take a bowl
}
V(lck);

//Dry rice

P(lck);                             //Mutually exclusive access array
chopsticks[i] = false;              //Put down your left chopsticks
chopsticks[(i + 1) % n] = false;    //Put down your right chopsticks
bowls--;                            //Release bowl
V(lck);
}
}
```

Keywords: Algorithm multiple processes

Added by olechka on Thu, 23 Dec 2021 03:57:41 +0200