Linux process control process creation, termination, waiting

()Hi! Hello, this is the homepage of ky233 ky233_-CSDN Blog First Introduction to Linux Process, C++ Classes and Objects, C++ Classes and Objects Part 1 https://blog.csdn.net/ky233?type=blog

Please follow me to avoid getting lost?’?’?

Table of Contents

1. Process creation

1. Understanding of fork function

1. Please describe what the operating system does when fork creates a child process?

2. After fork, the code of the parent and child processes is shared, so is it only shared after that or all of them?

2. Copy on write

2. Process termination

1. What does the operating system do when the process terminates?

2. Common ways of process termination

1. So why does the main function return 0 in the end?

2. The third situation

3. How to terminate a process using code

1. What is a correct termination?

3. Process waiting

1. Why should there be a process waiting?

2.wait and waitpid

1.wait

2.waitpid

3. How does the parent process get the exit result of the child process?


1. Process Creation

1. Understanding of fork function

Since I have talked about part of the fork before, I won’t introduce it too much here. I will just talk about the interview questions separately.

1. Please describe, when fork creates a child process, what does the operating system do?

Create a child process and allocate the corresponding kernel data structure to the child process. The child process must be independent. Because the process is independent, in theory the child process must have its own code and data, but we do not have a loading process, so The child process borrows the code of the parent process, and the data can be modified, so the parent and child processes must be separated.

2. After the fork, the code of the parent and child processes is shared, then Is it only shared later or all of them?

It should be noted here that when using fork, it is not the code after the fork that is shared, but all the code will be shared.

This is because the process may be interrupted at any time, and it must continue running from the previous position next time it comes back. Therefore, there is corresponding register data in the CPU to record the execution position of the current process, and because the data in the register can There are multiple copies, so when creating, although the parent and child processes are scheduled separately, the context saved in the register of the parent process in the fork register is also shared by the child process, so after the fork, the child process runs the code after the fork. . (In other words, when it was created, the execution location of the parent process was also copied, so it was executed next, which does not mean that the child process cannot access the previous data)

2.Copy on write

I don’t know if you still remember that the same data of the parent and child processes of the fork function, accessed at the same address and at the same time, has two different values. This is called copy-on-write.

So why have realistic copies?

This is because when creating a child process, there is no need to copy data that will not be accessed or can only be read, but the OS does not know what kind of data will be written. Even if it knows, will it be written in advance if it is copied? ? This is not necessarily the case, so the operating system uses copy-on-write to separate the data of the parent and child processes! This is an efficient way to use memory! !

This picture makes it very clear. When the child process is first created, our parent and child processes are exactly the same. When the child process wants to modify the contents of the physical memory, it will copy the shared data and then modify the page table. pointing.

So why there is a realistic copy summary:

  • Because of the existence of copy-on-write, the father and son processes can be completely separated! Completed the technical guarantee of process independence.
  • Copy-on-write is a delayed application technique that improves overall performance

2. Process Termination

1. What does the operating system do when the process terminates?

This topic is very simple. Of course, it is to release the relevant kernel data structures and corresponding data codes applied by the process. In essence, it is a release of resources.

2. Common ways of process termination

  1. After the code is run, the result is correct.
  2. After the code is run, the result is incorrect.
  3. The code is not finished and the result is incorrect.

The first two questions can be discussed together,

1. So why does the main function always return 0 in the end?

 1 #include <stdio.h>
  2 int main()
  3 {
  4 printf("hello Linux\\
");
  5
  6 return 10;
  7 } 

Why does the code always end up with 0?

But in fact, the return value of the main function is not always 0. This is the exit code of the process. Among them, 0 means the result is correct, and non-0 means the result is incorrect.

We can get the exit code of the latest process through the following command: echo $?

This is returned to the previous process to evaluate the execution results of the process. We can judge the return value to determine whether the code you wrote is correct. If the return value is correct, the result you want is 0. If not, the if will directly return a non-0 number. There are countless non-0 values. This is used to represent the causes of different errors, making it easier to locate the cause of the error.

We can use strerror to print common error codes

 4 int main()
  5 {
  6 int i = 0;
  7 for(i=0;i<150;i + + )
  8     {
  9 printf("%d:%s\\
",i,strerror(i));
 10
 11 }
 12 // printf("hello Linux\\
");
 13
 14 return 0;
 15}

We can Use these exit codes, or you can define your own.

2. The third situation

When the program crashes, the exit code is meaningless and the return statement is generally not executed.

3. How to terminate a process with code

1. What is a correct termination

The first is the return statement. In main, it terminates the process. In other functions, it returns to the superior level.

There is also exit code that terminates as a process at any time.

void print()
  6 {
  7 printf("hello world\\
");
  8 exit(0);
  9 }
 10
 11 int main()
 12 {
 13 print();
 14 printf("hello Linux\\
");
 15
 16 return 0;
 17}

We can see that the program only ran “hello world” and then exited.

3. Process waiting

1. Why is there a process waiting

The first point: If the parent process ignores the child process, the child process will be in a zombie state, which will cause memory leaks.

Second point: The parent process depends on the status of the child process.

To sum up, the parent process recycles the resources of the child process and obtains the exit information of the child process through process waiting.

2. How to wait and what to wait for?

2.wait and waitpid

1.wait

First, we can see that the status of the child process is a zombie process at this time.

Then after we use wait, the parent process will wait for the child process to finish running and be recycled to avoid memory leaks caused by the zombie process. Note that wait defaults to the parent process blocking and waiting!

5 int main()
    6 {
    7 pid_t id=fork();
    8 if(id==0)
    9     {
   10 int con=5;
   11 while(con)
   12 {
   13 printf("I am a child process,pid:%d,ppid:%d\\
",get pid(),getppid());
   14 con--;
   15}
   16 exit(0);
   17}
   18 else{
   19 printf("I am the parent process\\
");
W> 20 pid_t ret = wait(NULL);
   twenty one
   twenty two     }
   23 return 0;
   twenty four }

2.waitpid

pid_t waitpid(pid_t pid, int* status, int options);

pid represents the pid of the waiting child process, where the pid here has three states

  1. If it is greater than 0, it is waiting for the specified process.
  2. Equal to 0, don’t worry about it now
  3. Equal to -1, it is waiting for any child process to exit. It’s arbitrary! Equivalent to wait

status represents the status, which is an integer. The high 16 bits are not involved for the time being. Among the low 16 bits, the second low 8 bit represents the exit code. The 7 bit represents core dump, and the low 7 bit represents the termination signal.

  1. If you want to get the child process exit code: status >> 8 & 0xFF. It is more recommended to use the macro provided by the system, WIFEXITED(status): If it is the status returned by the normal termination of the child process, it is true. (Check whether the process exited normally)
  2. If you want to get the termination signal, it is status & amp; 0x7F. We also recommend the macro provided by the system, WEXITSTATUS(status): If WIFEXITED is non-zero, extract the child process exit code. (View the exit code of the process)

options are options. You can choose whether the parent process needs to block and wait for the child process to exit.

  1. The default is 0: represents blocking waiting, which means the parent process has done nothing and has been waiting for the child process to exit.
  2. WNOHANG: It is called non-blocking waiting. In non-blocking waiting, the parent process continues to execute downwards, and after a while, it repeatedly verifies whether the child process has exited.

3. How does the parent process get the exit result of this child process?

We all know that processes are independent, and the process exit code is also the data of the child process. So how does the parent process get it?

Our PCB structure stores the exit result information of any process exit. The essence is to read the PCB structure of the child process! These two functions are called by the system, that is, the operating system. It is the OS that puts the exit information in the PCB structure of the child process into the status number in the form of a bitmap!

The knowledge points of the article match the official knowledge files, and you can further learn relevant knowledge. Cloud native entry-level skills treeHomepageOverview 16773 people are learning the system