# [operating system ⑧] - semaphore AND PV operation [philosopher dining problem AND semaphore semaphore semaphore set mechanism]

🌧 It's getting cooler in Nanjing

drink more hot water...☕️

Previous article address link: [operating system ⑦] - semaphore and PV operation (Part I) [classic problems of producers and consumers].

# 1, Dining problem of philosophers

● Problem Description: there are five philosophers whose way of life is to think and eat alternately. They shared a round table and sat on five chairs. There are five bowls and five chopsticks on the round table. Usually, a philosopher thinks. When he is hungry, he tries to use the chopsticks closest to him on the left and right. He can eat only when he gets two chopsticks. After dinner, put down your chopsticks and continue to think.

● if according to [operating system ⑦] - semaphore and PV operation (Part I) [classic problems of producers and consumers] If we use recording semaphores to process:

```/* Pseudo code written based on C language */
semaphore chopstick[5] = {1, 1, 1, 1, 1}; 		// Chopsticks are resources, and the five chopsticks are set as mutually exclusive semaphores with an initial value of 1
while(true)
{
"The first i The process of a philosopher Pi():"				// i = 1, 2, 3, ..., a
while(true)
{
wait(chopstick[i]);				// Pick up the chopsticks in your left hand
wait(chopstick[(i+1) % 5]);		// Pick up the chopsticks with your right hand
eat();
signal(chopstick[i]);				// Put down your left chopsticks
signal(chopstick[(i+1) % 5]);		// Put down your right chopsticks
think();
}
}
```

◆ code Description: wait(...) is the P operation. signal(...) is the V operation.

● this code seems to solve the problem, and it seems to be no problem, but careful analysis will find that if each of the five philosophers is hungry and picks up the chopsticks on the left at the same time, the five semaphores are all 0. When they try to pick up the chopsticks on the right again, they will wait indefinitely because they have no chopsticks, which may cause deadlock.

how to solve this problem?
① method 1: at most four philosophers are allowed to take the left chopsticks at the same time, which can finally ensure that at least one philosopher can eat, and release two chopsticks for others to use after use.
② method 2: eating is allowed only when the philosophers pick up both left and right chopsticks.
③ method 3: stipulate that odd numbered philosophers take left chopsticks first and then right chopsticks, while even numbered philosophers take the opposite.

methods 1 AND 3 can be realized through algorithm design (at the same time, the problem can be solved with the previous recorded variables). However, method 2 is different (involving the content of this article). Let's study method 2. Next, we will introduce AND semaphore AND semaphore set mechanism.

# 2, AND semaphore

● AND semaphore: it refers to the semaphore operation when multiple resources are required at the same time AND each resource is occupied. When a piece of processing code needs to obtain two or more critical resources at the same time, there may be a situation that each process obtains part of the critical resources AND waits for the remaining critical resources. Each process will "give way to each other", resulting in deadlock.

● basic idea of AND semaphore: multiple critical resources required to apply for the whole section of code in a primitive, either all of them or none of them.

● AND semaphore P primitive is sweet (simultaneous wait), AND V primitive is Ssignal(Simultaneous Signal). Both are defined as follows:

```/* Pseudo code written based on C language */
"Swait(s_1, s_2, ..., s_n) operation"
semaphore s_1, s_2, ..., s_n Initialize;
procedure Swait(s_1, s_2, ..., s_n)
{
if (s_1 >= 1 and s_2 >= 1 and ... and s_n >= 1)
{
for( int i = 1; i<= n ;i++ )
s_i = s_i - 1;
}
else
{
blockProcessAndResetPC(s_firstless);	// block
}
}

"Ssignal(s_1, s_2, ..., s_n) operation"
semaphore s_1, s_2, ..., s_n Initialize;
procedure Ssignal(s_1, s_2, ..., s_n)
{
for( int i = 1; i<= n ;i++ )
s_i = s_i + 1;
wakeupProcess(s_i);		// awaken

}
```

◆ code Description:
① the swarm operation means to obtain resources. s1 to sn represent the required resources. When the number of resources is greater than 1, you can apply for each resource. After allocating the resources, the cycle jumps out and the swarm operation ends. If one of the resources si is not satisfied, the content in else will be executed: put the process into the blocking queue associated with si, and then the program counter will move the pointer to the start of the swarm operation. (the wait operation is a primitive. It must be executed if it is followed. If it cannot be executed, it must be re executed from the beginning.)
② the Ssignal operation means to release resources. It will release all resources from s1 to sn, empty all the blocking queues associated with s1 to sn, and schedule the processes in the blocking queue directly to the ready queue.
③ in swarm, the order of each semaphore is not important. Although it will affect which blocking queue the process belongs to, because either all resources are allocated or not allocated, there are always processes that obtain all resources and release resources after advancing, so they will not deadlock.

● use AND semaphore to solve the following problem: [no deadlock]

```/* Pseudo code written based on C language */
semaphore  chopstick chopstick[5] = {1, 1, 1, 1, 1};
do
{
think();
Sswait(chopstick[i], chopstick[(i+1) % 5]);		// Chopsticks with left and right hands can only be picked up left and right
eat();
Ssignal(chopstick[i], chopstick[(i+1) % 5]);		// Put down the chopsticks of both hands at the same time
}while(true)
```

● AND semaphores meet the use scenario of "multiple resources, the number is 1", but in fact, there will be scenarios where the number of multiple resources is not fixed. AND semaphores obviously can not handle the process scheduling in this situation. In order to solve the situation of multiple resources AND large number, semaphore sets appear.

# 3, Semaphore set

● semaphore set: refers to the semaphore processing when multiple resources are required at the same time, the number of each resource is different, and there is a critical value for the allocable resources. Since n critical resources of a certain type are required at one time, if these n critical resources are applied through n wait operations, the operation efficiency is very low and deadlock may occur.

● basic idea of semaphore set: expand on the basis of AND semaphore set, AND complete all resource applications in one primitive operation. The process's test value for semaphore si is ti (indicating the judgment condition of semaphore, requiring si > ti, that is, when the resource quantity is higher than ti, it will be allocated; when it is lower than ti, it will not be allocated), AND the occupancy value is di (indicates the requested amount of resources, i.e. s1 = si - di). The corresponding P AND V primitive formats are:

```/* Pseudo code written based on C language */
"Swait(s_1,t_1, d_1, ..., s_n, t_n, d_n) operation"
semaphore s_1, s_2, ..., s_n Initialize;
procedure Swait(s_1, s_2, ..., s_n)
{
if (s_1 >= t_1 and s_2 >= t_2 and ... and s_n >= t_n)
{
for( int i = 1; i<= n ;i++ )
s_i = s_i - d_i;
}
else
{
blockProcessAndResetPC(s_firstless);	// block
}
}

"Ssignal(s_1, d_1, ..., s_n, d_n) operation"
semaphore s_1, s_2, ..., s_n Initialize;
procedure Ssignal(s_1, s_2, ..., s_n)
{
for( int i = 1; i<= n ;i++ )
s_i = s_i + d_i;
wakeupProcess(s_i);		// awaken
}
```

● general "semaphore set" can be used for resource allocation and release in various situations. The following are several special cases:
① Swarm (s, D, d) means that D resources are applied for each time. When the number of resources is less than D, they will not be allocated.
② sweet (s, 1, 1) represents mutually exclusive semaphores.
③ Swarm (s, 1, 0) can be used as a controllable switch (when s ≥ 1, multiple processes are allowed to enter the critical area; when s = 0, any process is prohibited to enter the critical area).

● rewrite "reader / writer problem" with semaphore set: (the practice of recording semaphore is in the previous article: [operating system ⑦] - semaphore and PV operation (Part I).)
● Problem Description: there are two groups of concurrent processes, including many readers and many writers, sharing a file. Requirements:
(2) only one writer is allowed to write to the file.
(3) any writer shall not allow other readers or writers to work before completing the writing operation.
(4) the writer should let all existing writers and readers quit before performing the write operation.

```/* Pseudo code written based on C language */
int RN;						// Number of readers
semaphore L = RN, mx = 1;
{
while(true)
{
Swait(L, 1, 1);
Swait(mx, 1, 0);		// When mx ≥ 1, multiple processes are allowed to enter the critical area; When mx = 0, no process is allowed to enter the critical zone
// Readers coming in will also deprive mx semaphores
...
...
Ssignal(L, 1);
}
}

void writer()
{
while(true)
{
Swait(mx, 1, 1);		// Or use Swarm (L, RN, 0)
...
write();
...
Ssignal(mx, 1);
}
}

void main()
{
writer();
}
```

# 4, Refer to appendix:

[1] Operating system A
For class

[2] Operating system tutorial
Teaching materials for class

[3] Synchronization and mutual exclusion of processes (9)
Written on Linux

[4] Semaphore