PV primitive processes the synchronization and mutex between processes through the operation semaphores. Its core is an inseparable and uninterrupted program.
The concept of semaphore was proposed by the famous Dutch computer scientist Dijkstra in 1965. The basic idea is to use a new variable type (semaphore) to record the current available resources.
The number of sources. There are two implementation methods: 1) semaphore must be greater than or equal to 0. 0 indicates that there are no idle resources, and a positive number indicates the number of idle resources.
(2) The semaphore value can be positive or negative. The absolute value of a negative number indicates the number of processes waiting to enter the critical section.
Semaphores are maintained by the operating system. User processes can only be accessed through initialization and two standard primitives (P and V. You can specify a non-negative integer for initialization, that is, the total number of idle resources.
P primitive: P is the first letter of the Dutch proberen (test. Is the blocking primitive, responsible for converting the current process from the running state to the blocking state until another process wakes up. The operation is as follows: apply for an idle resource (subtract 1 from the semaphore). If it succeeds, it exits. If it fails, the process is blocked;
V primitive: V is the first letter of Dutch verhogen (ADD. The wake-up primitive is used to wake up a blocked process. It has a parameter table that stores information about the process waiting to be awakened. The operation is to release a occupied Resource (add the semaphore to 1). If a blocked process is found, select a wake-up process.
The operations on semaphores by PV primitives can be divided into three types:
1) regard semaphores as a lock sign to achieve mutex access to a shared variable.
Implementation process:
P (mutex); // The initial mutex value is 1.
Access the shared data;
V (mutex );
Non-critical section
2) regard semaphores as the remaining number of shared resources of a certain type to achieve access to a type of shared resources.
Implementation process:
P (Resource); // The initial value of resource is the number of resources n.
Use this resource;
V (Resource );
Non-critical section
3) Use semaphores as the tool for synchronizing data between processes.
Implementation process:
Critical section C1; P (S );
V (s); Critical Zone C2;
The following are examples:
Example 1: at the door of a supermarket, we have prepared 100 trolleys for each customer. Each customer takes a stroller when they go in to buy things, and then returns the carts after the purchase is completed. Use the P and V Operations to correctly synchronize the mutex between customer processes.
Analysis: A trolley is regarded as a resource. Each customer is a process that requires mutual access to the resource. Therefore, this example is the second application type of the PV primitive.
Solution: semaphore s_cartnum; // Number of idle trolleys. The initial value is 100.
Void consumer (void) // customer Process
{
P (s_cartnum );
Shopping;
Checkout;
V (s_cartnum );
}
Example 2: There is a fruit tray on the table. Each time you put a fruit in it. Dad puts apples on the plate, and his son eats the apples on the plate. I think of my father and son as two processes. I tried P and V Operations to correctly execute these four processes concurrently.
Analysis: Father and Son processes are mutually restricted. After the father process is executed and put into the drive, the son process can be executed to eat the apple. Therefore, this is a problem of inter-process synchronization.
Solution: semaphore s_platenum; // the disk capacity. The initial value is 1.
Semaphore s_applenum; // Number of apples. The initial value is 0.
Void father () // parent process
{
While (1)
{
P (s_platenum );
Put an apple into the plate;
V (s_applenum );
}
}
Void son () // son Process
{
While (1)
{
P (s_applenum );
Remove the apple from the drive;
V (s_platenum );
Eat apple;
}
}
The following is an example of using the PV primitive to solve process synchronization and mutex:
For typical IPC problems, such as producer-consumer, reader-writer, philosopher dining, and sleeping hairdresser, refer to relevant teaching materials.
1. Two processes, Pa and Pb, are connected through two FIFO (first-in-first-out) buffer queues ()
Pa
PB
Q1
Q2
Pa retrieves messages from Q2, processes messages to Q1, and Pb fetches messages from Q1. After processing, messages are sent to Q2. The length of each buffer zone is equal to the length of the sent message. q1 queue length is N, Q2 queue length is M. assume that messages are fully loaded in Q1 at the beginning, and try the P and V Operations to solve the problem of inter-process communication.
Solution: // The number of idle buffers in the q1 queue. The initial value is 0.
Semaphore s_buffnum_q1;
// The number of idle buffers in the Q2 queue. The initial value is M.
Semaphore s_buffnum_q2;
// The number of messages in the q1 queue. The initial value is N.
Semaphore s_messagenum_q1;
// The number of messages in the Q2 queue. The initial value is 0.
Semaphore s_messagenum_q2;
Void PA ()
{
While (1)
{
P (s_messagenum_q2 );
Retrieve a message from Q2;
V (s_buffnum_q2 );
Process messages;
Generate a new message;
P (s_buffnum_q1 );
Send the message to Q1;
V (s_messagenum_q1 );
}
}
Void Pb ()
{
While (1)
{
P (s_messagenum_q1 );
Retrieve a message from Q1;
V (s_buffnum_q1 );
Process messages;
Generate a new message;
P (s_buffnum_q2 );
Send the message to Q2;
V (s_messagenum_q2 );
}
}
II. The final examination of the "Operating System" course will be held soon. Assuming that both students and invigilators are considered as processes, there will be n students and 1 teacher. Only one person can be in or out at the entrance of the test room. The principle for entering the test room is
First come advanced. After N students enter the test room, the instructor can issue a paper. Students can leave the test room after handing in their papers, and teachers can leave the test room only after receiving all the papers and encapsulating them.
(1) How many processes need to be set?
(2) Use the P and V Operations to solve the synchronization and mutex relationships in the above problems.
Solution: semaphore s_door; // whether the door can be accessed or not. Initial Value: 1
Semaphore s_studentready; // check whether students arrive at the same time. The initial value is 0.
Semaphore s_exambegin; // starts the test. The initial value is 0.
Semaphore s_examover; // The test is over. The initial value is 0.
Int nstudentnum = 0; // Number of Students
Semaphore s_mutex1 // mutex semaphore, initial value: 1
Int npapernum = 0; // number of submitted volumes
Semaphore s_mutex2 // mutex semaphore, initial value: 1
Void student ()
{
P (s_door );
Entry;
V (s_door );
P (s_mutex1 );
Nstudentnum ++; // increase the number of students
If (nstudentnum = N) V (s_studentready );
V (s_mutex1 );
P (s_exambegin); // wait for the instructor to announce the start of the test
Exam...
Submit the paper;
P (s_mutex2 );
Npapernum ++; // increase the number of exam parts
If (npapernum = N) V (s_examover );
V (s_mutex2 );
P (s_door );
Go out;
V (s_door );
}
Void teacher ()
{
P (s_door );
Entry;
V (s_door );
P (s_studentready); // wait for the last student to wake up
Publish a volume;
For (I = 1; I <= N; I ++) V (s_exambegin );
P (s_examover); // wait until the test ends.
Encapsulate exam;
P (s_door );
Go out;
V (s_door );
}
3. A store has two types of foods, A and B. The maximum quantity is M.
The store sells both A and B types of food, each with one. To avoid food deterioration, follow the principle of first-to-first-sale food. Two food companies supply a and B continuously (one food each time ).
To ensure normal sales, when the number of foods in a certain type exceeds K (k <m), a large number of foods are suspended for purchase and a small number of foods are supplemented.
(1) How many processes need to be set?
(2) Use the P and V Operations to solve the synchronization mutex in the above problem.
Solution: semaphore s_buffnum_a; // Number of buffers for A, initial value m
Semaphore s_num_a; // number of a. The initial value is 0.
Semaphore s_buffnum_ B; // Number of buffers of B, initial value m
Semaphore s_num_ B; // number of B. The initial value is 0.
Void shop ()
{
While (1)
{
P (s_num_a );
P (s_num_ B );
Take out one food item A and one food item B respectively;
V (s_buffnum_a );
V (s_buffnum_a );
Sell the food together;
}
}
// "A food plus 1, while B food unchanged" this situation allows the number of times (the number of licenses), the value is equal to // K-(A-B), the initial value is K
Semaphore s_a_ B;
// "B food plus 1, while a food remains unchanged" this situation allows the number of occurrences (the number of licenses), the value is equal to // K-(B-A), the initial value is K
Semaphore s_ B _a;
Void producer_a ()
{
While (1)
{
Produce a food;
P (s_buffnum_a );
P (s_a_ B );
Provide the store with a food;
V (s_num_a );
V (s_ B _a );
}
}
Void producer_ B ()
{
While (1)
{
Produce B food;
P (s_buffnum_ B );
P (s_ B _a );
Provide B food to stores;
V (s_num_ B );
V (s_a_ B );
}
}
4. There is only one bathroom in a student apartment. The bathroom is very small and can accommodate only one person at a time. Boys and girls living in the apartment had to share the bathroom. Therefore,
The building chief has the following bathroom use rules: (1) only one person can use the bathroom at a time; (2) girls have a higher priority than boys, that is, if both boys and girls are waiting to use the bathroom, girls are given priority;
(3) For people with the same sex, use the principle of first come first.
Hypothesis:
(1) When a boy wants to use the bathroom, he will execute a function boy_wants_to_use_bathroom. When he leaves the bathroom, he will also execute another function boy_leaves_bathroom;
(2) When a girl wants to use the bathroom, she will execute the girl_wants_to_use_bathroom function. When she leaves, she will also execute the girl_leaves_bathroom function;
Problem: Use semaphores and P and V Operations to implement these four functions (initial state: the bathroom is empty ).
Solution: semaphore definition:
Semaphore s_mutex; // mutex semaphores. The initial values are 1.
Semaphore s_boys; // boys' waiting queue. The initial value is 0.
Semaphore s_girls; // The waiting queue for girls. The initial value is 0.
Definition of common variables:
Int boys_waiting = 0; // number of boys waiting;
Int girls_waiting = 0; // Number of girls waiting;
Int using = 0; // whether the bathroom is currently in use;
Void boy_wants_to_use_bathroom ()
{
P (s_mutex );
If (using = 0) & (girls_waiting = 0 ))
{
Using = 1;
V (s_mutex );
}
Else
{
Boys_waiting ++;
V (s_mutex );
P (s_boys );
}
}
Void boy_leaves_bathroom ()
{
P (s_mutex );
If (girls_waiting> 0) // give priority to wake up girls
{
Girls_waiting --;
V (s_girls );
}
Else if (boys_waiting> 0)
{
Boys_waiting --;
V (S _ boys );
}
Else using = 0; // no one is waiting
V (s_mutex );
}
Void girl_wants_to_use_bathroom ()
{
P (s_mutex );
If (using = 0)
{
Using = 1;
V (s_mutex );
}
Else
{
Girls_waiting ++;
V (s_mutex );
P (s_girls );
}
}
Void girl_leaves_bathroom ()
{
P (s_mutex );
If (girls_waiting> 0) // give priority to wake up girls
{
Girls_waiting --;
V (s_girls );
}
Else if (boys_waiting> 0)
{
Boys_waiting --;
V (S _ boys );
}
Else using = 0; // no one is waiting
V (s_mutex );
}