In-depth analysis of Linux process management

0 Summary

The last article https://blog.csdn.net/CZHLNN/article/details/114534969?spm=1001.2014.3001.5501 has introduced the concept of process, so in this article I intend to explain process control from the entire life cycle of the process ----> Four aspects of process creation, process termination, process waiting, and process program replacement are analyzed.

1 Process creation

1.1 fork function

The fork function is a very important function in Linux. It creates a new process from an existing process. The new process is the child process, and the original process is the parent process. The characteristics of the function are as follows:

Insert picture description here
The following is a sample code that creates a child process in a process. The
Insert picture description here
results are as follows:
Insert picture description here

Process child process created in fact be described: after a call to fork system call from a child process has, fork to create a child process is the parent process as a template, create success after the child returns to 0 , to the current process (parent process) Return the process id of the child process . What the kernel does is:

  • Allocate a new memory block and a data structure describing the process to the child process
  • Copy part of the data structure content of the parent process to the child process
  • Add child process to the system process list
  • fork returns, start scheduler scheduling

Note: The parent process executes independently before fork, and after fork, the two execution streams of the parent and child run separately. And after fork, who executes first is completely determined by the scheduler.

1.2 Copy-on-write

Generally, the code of the parent and child processes are shared. At the same time, when the parent and child processes do not write data, the data is also shared. When either party executes the operation of writing data, each copy of the written data is performed by copy-on-write. Size copy. See the figure below for details.
Insert picture description here

When the parent process creates the child process, the OS sets the code and data to read-only. Once the parent/child process wants to write data, it will trigger the copy-on-write, copy the data to be written to other locations in the memory, As shown in the right part of the above figure, the copy-on-write technology also ensures the independence between processes.

1.3 Fork general usage

  • A parent process wants to copy itself so that the parent and child processes execute different code segments (logic) at the same time. For example, the parent process waits for a client request and spawns a child process to handle the request.
  • A process needs to execute a different program. For example, after the child process returns from frok, call the exec function.

1.4 Reasons for fork call failure

  • Too many processes in the system
  • The number of processes of the actual user has reached the upper limit

1.5 Summary

How to understand process creation? How to understand fork?
Insert picture description here

2 Process termination

2.1 Process exit

  • The code has finished running and the result is correct
    Insert picture description here

  • The code has finished running, but the result is incorrect
    Insert picture description here

  • Code terminated abnormally
    Insert picture description here
    Insert picture description here

2.2 Common exit methods of processes

Normal termination (you can check the process exit code through echo $?)
In the C/C++ function design, 0 generally means that it is correct

  • Return return 0 from the main function;
  • Call exit
  • Call _exit

The difference between return and exit

  • exit : Terminate the entire process, any call will terminate, and exit (number), the number is the exit code of the process
  • return : Call the termination function. Only in the main function is the termination function, and in other functions it represents the return value . The return number in main, the number is the exit code of the process .

The difference between exit and _exit:

  • exit will refresh the data in the buffer, but _exit will not.

Abnormal exit

  • Ctrl + c, the signal is terminated, that is, the OS will kill the process, which will be discussed in the signal article later.

3 Process waiting

3.1 The necessity of process waiting

  • First of all, if the child process exits, if the parent process ignores it, it may cause a "zombie process" problem, which may lead to memory leaks.
  • Secondly, once a process becomes a zombie state, it will be invulnerable, and the "kill -9 without blinking" can do nothing, because no one can kill a dead process.
  • Finally, we need to know how the tasks assigned by the parent process to the child process are completed. For example, if the child process is completed, the result is correct or not, or whether it exits normally.
  • The parent process obtains the exit information of the child process through the process of waiting, and triggers the OS to reclaim the resources of the child process. That is, blocking and waiting: blocking yourself and waiting for the execution of the child process.

3.2 How the process waits

3.2.1 wait

Insert picture description here
return value

  • Return the pid of the waiting process on success, return -1 on failure

parameter

  • Output parameter, get the exit status of the child process, if you don’t care, you can set it to NULL

Insert picture description here

3.2.1 waitpid

Insert picture description here
pid_t waitpid(pid_t, int * status, int options);

  • return value:

When returning normally, waitpid returns the process ID of the collected child process;
if WNOHANG is set, and during the call, waitpid finds that there is no child process that has exited to collect at this moment, and returns 0 ;
if there is an error in the call, this Errno will be set to the corresponding value to indicate where the error is;

  • parameter

pid:
pid = -1, waiting for any child process, equivalent to wait
pid> 0, waiting for the child process whose process id is equal to the parameter pid
status:
this parameter is an output parameter, the child process exits and becomes a zombie process, the parent process Call waitpid on the one hand to read the exit code and exit signal information of the child process, so it is necessary to pass in an output parameter, int * status, the value of this status is actually in the PCB of the child process, through the analysis of the status , You can get the exit status information of the child process, the result of the code running is correct, the result of the code running is wrong, and the process terminates abnormally.
We can look at the exit code and signal information in the PCB source code of the kernel process:
Insert picture description here
WIFEXITED(status): If the child process is terminated normally (including: the result of the code is correct, the result of the code is incorrect), then True, it is used to check whether the process exited normally.
WEXITSTATUS(status): If the above expression is true (not 0), the exit code of the child process is proposed, which is used to extract the exit code of the child process.

options:

WNOHANG: If the child process specified by pid has not ended, the waitpid() function returns 0 and no wait is given. If it ends normally, it returns the id of the child process for non-blocking waiting.

Get child process status

  • Both wait and waitpid have a status parameter, which is an output parameter and is filled in by the operating system.
  • If NULL is passed, it means that you don't care about the exit status information of the child process, otherwise the operating system will feed back the exit information of the child process to the parent process according to this parameter.
  • Status cannot be simply treated as an integer, but as a bitmap. The details are as follows (only the lower 16 bits are studied):
    Insert picture description here
    Example of waitpid usage:
    Insert picture description here
    Insert picture description here
    Insert picture description here
    Insert picture description here
    Insert picture description here

4 Process program replacement

4.1 Replacement principle

After creating the child process with fork , it executes the same program as the parent process (but it is very possible to execute a different code branch), and the child process often needs to call the exec function to execute another program. When a process calls an exec function, the user space code and data of the process are completely replaced by the new program, copy-on-write occurs, and calling exec does not create a new process, so the process id does not change before and after calling exec.

Insert picture description here

4.2 How to replace

Complete the replacement function interpretation by calling the function at the beginning of exec
Insert picture description here

  • If these functions are successfully called, a new program will be loaded and executed from the startup code without returning.
  • If the call fails, it returns -1.
  • So the exec function only has an error return value but no success return value.

Naming comprehension

  • l(list): Indicates that the parameter adopts a list
  • v(vector): Array for parameters
  • p(path): automatically search environment variable PATH with p
  • e(env): Indicates that you maintain environment variables
    Insert picture description here
int main()
{
    
    

 char *const argv[] = {
    
    "ps", "-ef", NULL};
 char *const envp[] = {
    
    "PATH=/bin:/usr/bin", "TERM=console", NULL};
 
 execl("/bin/ps", "ps", "-ef", NULL);
 
 // 带l的需要使用列表传参,并以NULL结尾
 // 带p的,可以使用环境变量PATH,无需写全路径
 execlp("ps", "ps", "-ef", NULL);
 
 // 带e的,需要自己组装环境变量
 // 带v的需要输赢数组传参,数组以NULl结尾
 execle("/bin/ps", "ps", "-ef", NULL, envp);
 execv("/bin/ps", argv);
 
 // 带p的,可以使用环境变量PATH,无需写全路径
 execvp("ps", argv);
 
 //带e的需要自己组装环境变量
 execv("/bin/ps",argv,envp);
 
 exit(0);
 }

In fact, only execve is a real system call, and the other five functions eventually call execve

Insert picture description here
Insert picture description here
I will write a mini shell parser in a later article, so stay tuned. *

Guess you like

Origin blog.csdn.net/CZHLNN/article/details/114801517