Reading Notes of Modern Operating System-inter-process communication 1

Source: Internet
Author: User
Tags alternation

In many cases, processes need to communicate with other processes. For example, the pipe command in shell: ps-ef | grep nginx, the output of one command, as the input of another process, is Interprocess Communication ).
 
Inter-process communication mainly needs to solve three problems:
 
1. How does one process transmit information to another process?
 
2. How to prevent mutual interference and obstruction between processes
 
3. What should I do when there is a dependency between processes.
 
Although the communication between processes is discussed here, the communication between threads needs to solve the last two problems. Because multiple threads are in the same process, they are also in the same address space. Therefore, the first problem is naturally well solved. However, the second and third problems still exist. Of course, the solution is similar to that of inter-process communication in dealing with these two problems. The following content involves the above three questions.
 
1. Race Condition)
 
In some operating systems, multiple processes share part of the memory, and each process can perform read and write operations on them. The shared memory may be stored in the memory or a shared file. To see the competition conditions between processes, a simple example is provided to describe the print pool. If a process wants to print a file, it will input the file name into the directory of the print pool. There is a printing process-printer daemon-which will check whether there are any files to be printed in the print pool directory at intervals. If yes, it will be printed and not pulled.
 
The printer directory is as follows:


 
 
Each small grid in the figure can store a file name to be printed (in fact, it should be a pointer to the file to be printed, here is just to illustrate the assumptions made ). Similarly, we also need to assume two shared variables: one is called out to store the name of the file to be printed, and the other is called in to store a small space in the file name to be printed. These two variables may be stored in another file, which is shared to all processes.
 
At the moment shown, units 1, 2, and 3 are empty. That is to say, the files in the previous step have been printed. The space between the 5th and 9th is empty. That is to say, the files to be printed are stored in the following units in sequence. At this time point, the variable in should be stored as 5. Assume that process A reads the variable in and obtains the value 5. Therefore, process A stores this value in its local variable next_free_slot. At this time, it happens that the CPU time slice has arrived, and process A is re-running, and process B obtains the time slice, when running, it also has files that need to be printed, so it reads in and obtains the value 5, so it also stores the value 5 in its local variable next_free_slot. Then, the variable value is used to store the file name of the printed file, which is saved as ccc.txt in cell 5. Wait for printing. Then process B starts to do other things. After a while, the CPU time slice of process B is used up. Process A obtains the CPU time slice. . Process B may be waiting for the output, but it will never be able to wait.
 
 
2. Critical Regions)
 
How can we avoid competition conditions? To avoid this problem, or any processing policy that involves shared memory, files, or all other shared resources is to prevent more than one process from reading and writing shared data at the same time. In other words, Mutual Exclusion ).
 
For most operating systems, selecting appropriate primitives to achieve mutex is a major method involved. The Critical Region/Critical Section refers to the parts in the process that access Shared Memory and may cause competition. To prevent competition, we can understand that we should prevent two processes that need to share the same piece of memory from entering their critical section at the same time.
 
However, this is not enough. We need to adhere to the following four principles:
Two processes are not allowed to enter their respective critical zones at the same time.
Do not make any assumptions about the CPU speed and number of CPUs
Processes running outside the critical section cannot block other processes.
No process is allowed to wait endlessly to enter its critical section.
The above describes an abstract solution to the problem. You can simply use a graph as an example to describe the concept of using a critical section to reflect mutex operations.
 
 
 
3. Solutions for mutual exclusion-Disable Interrupt)
 
In a single processor system, this is the simplest solution. That is, when a process enters the critical section, disable interruption and wait until it leaves the critical section before enabling. The premise that the CPU can switch the process is that the clock interruption or other interruptions can occur. This means that when a process enters the critical section, it cannot be deprived of the CPU right until it leaves the critical section.
This solution is obviously not attractive and has two disadvantages:
It is unwise to give the user process the right to disable the interruption. If a process is disabled and never starts again, the system will eventually die.
If multiple CPUs are used, when a process is disabled and interrupted, only the CPU in use will be affected. At this time, other processes on the CPU may still access the critical zone, go to modify shared memory content
However, this is a convenient technique for the operating system kernel. When the kernel is updating the ready progress table, it may disable interruption within several instruction periods.
In addition, the more mutex is implemented, the less it gets. After all, the current machines are all multi-core.
4. Solutions for mutual exclusion-Lock Variables)
The principle of this solution is to design a variable whose Initialization is 0. To enter the critical section of a process, first check the value of this variable. If it is 0, it can enter the critical section, and set the value of this variable to 1. when it leaves the critical section, set this variable to 0. in short, the variable 0 indicates that no process is in the critical section, and 1 indicates that a process is in the critical section.
However, this solution has the same problems as the printer mentioned above.
5. Implementation of mutually exclusive solutions-strict alternation)
The basic principle of this solution is as follows:
[Cpp]
While (TRUE ){
While (turn! = 0 ){
}
Critical_region ();
Turn = 1;
Noncritical_region ();
}
 
While (TRUE ){
While (turn! = 1 ){
}
Critical_region ();
Turn = 0;
Noncritical_region ();
}
The integer variable turn is used to track whether the process can enter its critical section. For process 0, it constantly checks whether the turn is equal to 0. If yes, it can enter its own critical section. If the turn is not equal to 0, it will continue to wait, and continuously checks the value of this variable. If process 0 enters the critical section, when it comes out, it sets turn to 1, that is, process 1 (another process) enters the critical section.
 
For process 1, it executes the second code, but the principle is the same. For a process, you must constantly check the value of a variable to determine whether it is your turn to enter the critical section. This situation is called busy waiting ). This should be avoided because it is a waste of CPU time. The lock implemented by busy waiting is called the spin lock ).
This solution has another problem. If the execution speed of two processes varies greatly. We assume that process 0 is much faster than process 1. At the beginning, the value of turn is 0, and process 0 enters the critical section. Soon, process 0 leaves the critical section, and the turn is set to 1. At this time, process 1 begins to enter the critical section, at this time, process 0 may have left the non-critical section and continuously monitors the turn value. Process 1 leaves the critical section, and the turn is set to 0 again. process 0 enters the critical section, and process 1 enters the non-critical section. Since process 0 runs fast, it quickly executes the code of the critical section again, sets turn to 1, and then executes the code of the non-critical section. Because process 0 is very fast and process 1 is very slow, it is likely that process 1 is still in the non-critical zone of the first time. At this time, process 0 has executed the code of the second non-critical zone, at this time, turn is still the value it just set -- 0. In fact, another process, process 1, is not in the critical section, but is struggling in the non-critical section. In this case, the process 0 can only be dry.
Therefore, it is obvious that this solution is not suitable for the large execution speed gap between multiple processes. The title of this section is strict alternation. For example, as mentioned above, strict alternation does not allow a process to submit more than one file to be printed at a time. This may also be to avoid a large execution speed gap between cities.
6. Several solutions to achieve process mutex-the Peterson Solution
The history of this solution is not mentioned here. The basic principle is as follows:
[Cpp]
# Define FALSE 0
# Define TRUE 1
# Define N 2
 
Int turn;
Int interested [N];
 
Void enter_region (int process ){
Int other;
Other = 1-process;
Interested [process] = TRUE;
Turn = process;
While (turn = process & intrested [other] = TRUE)
}
Void leave_region (int process ){
Intrested [process] = FALSE;
}
Before a process enters the critical section, it needs to execute the enter_region function and pass its process number as a parameter. When a process leaves the critical section, the leave_region function must be executed.
 
Let's take a look at the Principle: For process 0 and process 1. At first, no one was in the critical section. Now process 0 calls the enter_region function. First, process 0 sets intrested [0], an array element corresponding to itself, to TRUE, and the turn value to its own process number, that is, 0. Next, this step is critical. Perform a loop check. If the round turns to itself (turn = process), but another process is also very interested (intrested [other] = TRUE ). If this is done, do nothing and wait. Otherwise, the system enters the critical section.
If process 0 completes the code in the critical section, set intrested [0] to FALSE, which means that you do not need to enter the critical section at the moment.
In this solution, will there be two processes waiting for a deadlock? Let's take a look. Assume that process 0 and process 1 execute the turn = process Code almost simultaneously. If process 0 executes this statement first, and process 1 also executes this statement to erase the value set by process 0. Then process 0 can only wait in the while loop, and process 1 actually enters its critical section. That's why the while loop in the layer is very important.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.