Operating system~How does the semaphore mechanism achieve synchronization, solve the smoker problem, and solve the philosopher’s meal problem

Semaphore mechanism

The user process can operate on the semaphore by using a pair of primitives provided by the operating system, thereby easily achieving mutual exclusion and synchronization of processes.

A semaphore is actually a variable (it can be an integer or a more complex record variable). A semaphore can be used to indicate the amount of a certain resource in the system. For example, there is only one printer in the system and it can be set. A semaphore with an initial value of 1.

Primitive is a special program segment whose execution can only be done in one go and cannot be interrupted.
The primitives are implemented by the off/on interrupt instructions.
The main problem of the software solution is that "the various operations of entering the zone cannot be done in one go." Therefore, if the operations of entering and exiting the zone can be realized with "primitives", the problem can be avoided by making these operations "all in one go".

A pair of primitives:
wait(S) primitive and signal(S) primitive. The primitive can be understood as a function written by ourselves. The function names are wait and signal respectively. The semaphore s in parentheses is actually when the function is called A parameter passed in.

The wait and signal primitives are often abbreviated as P and v operations (from the Dutch proberen and verhogen). Therefore, when doing questions, wait(S) and signal(S) are often written as P(S) and v(S) respectively.

Integer semaphore

Use an integer variable as a semaphore to indicate the amount of a certain resource in the system.

The difference with ordinary integer variables: There are only three operations on semaphores, namely initialization, P operation, and V operation

Insert picture description here
Insert picture description here

Recorded semaphore

The defect of integer semaphore is the problem of "busy etc.", so people put forward the "recorded semaphore", that is, the semaphore represented by the recorded data structure.

The difference between the recorded semaphore and the integer semaphore is that there will be a blocking queue to avoid idling and busy phenomena.

Insert picture description here
Wait(S) and signal(S) in the title can also be denoted as P(S) and v(S). This pair of primitives can be used to realize the "application" and "release" of system resources. The initial value of S.value represents the number of a certain resource in the system.

Insert picture description here
A Р operation on the semaphore s means that the process requests a unit of this type of resource, so it needs to execute S.value–, which means that the number of resources is reduced by 1.
When S.value <0, it means that this type of resource has been allocated, so the process should Call the block primitive to self-block (the currently running process is from running state> blocking state), actively abandon the processor, and insert it into the waiting queue sL of this type of resource. It can be seen that this mechanism follows the principle of "giving power to wait", and there will be no "busy waiting" phenomenon.

A v operation on semaphore s means that the process releases a unit of this type of resource, so S.value++ needs to be executed, which means that the number of resources is increased by 1. If it is still S.value <=0 after adding 1, it means that there is still a process in it. Waiting for this type of resource, so the wakeup primitive should be called to wake up the first process in the waiting queue (the awakened process goes from blocking state → ready state).

to sum up

Insert picture description here

Semaphore mechanism to achieve mutual exclusion of processes

1. Analyze the key activities of concurrent processes and delimit the critical area (for example: access to the critical resource printer should be placed in the critical area)
2. Set the mutex semaphore mutex, the initial value is 1
3. Execute P before the critical area (mutex)
4. Execute v(mutex) after the critical section
Insert picture description here
Insert picture description here

Semaphore mechanism to achieve process synchronization

Use semaphores to achieve process synchronization:
1. Analyze where the "synchronization relationship" needs to be realized, that is, the two operations (or two sentences of code) performed by "one tandem" must be guaranteed.
2. Set the synchronization signal s, which is initially 0
3. Execute v(s) after "previous operation"
4.
Insert picture description here
If P(S) is executed before the "post operation", if the v(S) operation is executed first, then S++ after S=1. Later, when the P(S) operation is executed, because S=1, it means that there are available resources, S– will be executed, and the value of s will return to 0. The P2 process will not execute the block primitive, but continue to execute code 4 .
If the P(S) operation is executed first, since S=o, S– then S=-1, it means that there are no available resources at this time, so the block primitive will be executed in the P operation, and the block will be actively requested. After the code 2 is executed, the v(S) operation is executed, S++, and s is changed back to o. Since there is a process in the blocking queue corresponding to the semaphore at this time, the wakeup primitive will be executed in the v operation to wake up P2 process. So P2 can continue to execute code 4

Solving the smoker problem

Suppose a system has three smoker processes and one supplier process. Every smoker keeps rolling a cigarette and smoking it, but to roll up and smoke a cigarette, the smoker needs three materials: tobacco, paper and glue. Among the three smokers, the first had tobacco, the second had paper, and the third had glue. The supplier process provides three kinds of materials indefinitely. The supplier puts two materials on the table each time, and the smoker who owns the remaining material rolls a cigarette and smokes it, and sends a signal to the supplier process that it is completed , The supplier will put two other materials on the table. This process is repeated (let the three smokers smoke in turn)

Insert picture description here
In essence, this question also belongs to the "producer-consumer" problem. In more detail, it should be "single producer-multiple consumers who can produce multiple products."
Insert picture description here
1. Relationship analysis. Find out the various processes described in the title, and analyze the synchronization and mutual exclusion relationship between them.
2. Organize your ideas. Determine the approximate sequence of P and V operations according to the operation flow of each process
3. Set the semaphore. Set the required semaphore, and determine the initial value of the semaphore according to the subject conditions. (The initial value of the mutually exclusive semaphore is generally 1, and the initial value of the synchronization semaphore depends on the initial value of the corresponding resource)
Combination 1: Paper + glue
Combination 2: Tobacco + glue
Combination 3: Tobacco + paper
synchronization relationship (from the event From the perspective of analysis):
there is combination one on the table → the first smoker takes things off the
table there is combination two → the second smoker takes things off
there is combination three on the table → the third smoker takes things and
sends it out Signal → The supplier puts the next combination on the table.
PV operation sequence: "Front v and back P"

Insert picture description here

solve

Insert picture description here
The smoker problem can provide an idea for us to solve the "single producer who can produce multiple products".
The essence worth learning is: "Let each smoker take turns to smoke" necessarily requires "combination one, two, and three on the table in turn". Pay attention to how we use an integer variable i to achieve this "rotation" process .

Philosopher's meal problem

There are five philosophers sitting on a round table, a chopstick is placed on the table between every two philosophers, and in the middle of the table is a bowl of rice. Philosophers devote their life's energy to thinking and eating, and philosophers do not influence others when thinking. Only when the philosopher was hungry did he try to pick up the left and right chopsticks (one by one). If the chopsticks are already in the hands of others, you need to wait. The hungry philosopher can only start eating when he picks up two chopsticks at the same time. When the meal is over, he puts down the chopsticks and continues to think.
Insert picture description here
1. Relationship analysis. There are five philosopher processes in the system, and the five philosophers
and their neighbors' visits to their middle chopsticks are mutually exclusive. 2. Organize ideas. There is only mutual exclusion in this problem, but unlike
the problems encountered before , each philosopher process needs to hold two critical resources at the same time to start eating. How to avoid the deadlock phenomenon caused by improper distribution of critical resources is the essence of the philosopher's problem.
3. Semaphore settings. Define the mutually exclusive semaphore array
chopstick[5]={1,1,1,1,1} to implement mutually exclusive access to 5 chopsticks. And the philosophers are numbered 0~4, the chopsticks on the left of philosopher i are numbered i, and the chopsticks on the right are numbered (i+1)%5.

In order to avoid deadlock, when we use semaphore implementation, we must ensure that the philosopher holding the left chopsticks and the right chopsticks is a mutually exclusive thing

A more accurate statement should be: the use of chopsticks by philosophers must be mutually exclusive. This ensures that even if a philosopher is blocked while holding the chopsticks halfway through, no other philosopher will continue to try to hold the chopsticks. In this case, after the philosopher who is currently having a meal puts down his chopsticks, the blocked philosopher can get the chopsticks he is waiting for.

semaphore chopstick[5]={1,1,1,1,1};
semaphore mutex = 1;
//take the chopsticks
Pi () { //the process of the philosopher number i while(1){ P (mutex ); P(chopstick[i]); //take the left P (chopstick [(i+1)%5] );//take the right v (mutex); eat... v (chopstick[i]); //put Left v (chopstick[ (i+1) %5]); //Put the right and think... } }











Guess you like

Origin blog.csdn.net/Shangxingya/article/details/113801594