in the Linux system, the first process is inherent in the system, innate or is arranged by the kernel designer, after the kernel has booted and completed the basic initialization, there is the system first process (actually the kernel thread). In addition, all other processes and kernel threads are created by this primitive process or its descendant processes, and are descendants of this primitive process.
Linux divides the creation and execution of processes into two steps.
The first step is to copy a "subprocess" from the existing "parent process" like a cell division. The copied child process has its own TASK_STRUCT structure and system space stack, which shares all other resources with the parent process. For example, if the parent process opens five files, the child process also has five open files, and the current read and write pointers to the files are also parked in the same place, so this step is "copy". For this reason, the Linux system provides two system calls.
1) fork (): This call is copy-all, all the resources of the parent process are "passed" to the child process through the replication of the data structure, and the fork () call is a parameterless call.
2) Clone (): This call can selectively replicate a resource to a child process, whereas a data structure that is not replicated can be shared by the child process through a copy of the pointer. In extreme cases, a process can create a thread from clone (). Since there is a choice to copy, Clone () is a call to a parameter.
There is a similar call to fork () vfork (), without parameters, but all resources except task_struct and the system space stack are copied "genetically" through the data structure pointer. So, as in the extreme case of clone (), vfork out is a thread rather than a process (note the difference between processes and threads in a Linux system: for individual user threads, there is a separate task_struct and system space stack, but all share 3G user space For individual user processes, there is a separate task_struct, system space stack, and 3G user space).
The second step is the execution of the target program, in general, a process is created because there are different target programs to allow the new program to execute (). So to create a child process to "separate" from the parent process, go their own way, Linux for this provides a system call EXECVE (), so that a process can be executed as a file in the form of an executable program image.
After the child process has been created, the parent process has three choices. The first is to continue to go their own way, and the sub-process of parting. However, if the child process "dies" before the parent process, the kernel sends a banshee signal to the parent process. The second is to stop, go to sleep, wait for the child process to complete its mission to the final death, and then the parent process continues to execute. The system provides two system calls, WAIT4 () and Wait3 (). The two system calls are basically the same, WAIT4 () waits for a particular child process to die, and wait3 () waits for any one of the child processes to die. The third option is to "exit the historical stage by yourself" and end your life. Linux has set a system call exit () for this purpose. The third option is a special case of the first choice.
The following program demonstrates the "life cycle" of a process:
1#include <stdio.h>2 3 intMain ()4 {5 intChild ;6 Char*args[] = {"/bin/echo","Hello","world!", NULL};7 8 if(! (Child =Fork ()))9 {Ten /* Child*/ Oneprintf"pid%d:%d is my father\n", Getpid (), Getppid ()); AExecve ("/bin/echo", args, NULL); -printf"PID%d:i am back, something is wrong!\n", Getpid ()); - } the Else - { - intmyself =getpid (); -printf"pid%d:%d is my son\n", myself, child); +WAIT4 (Child, NULL,0, NULL); -printf"PID%d:done\n", myself); + } A return 0; at}
Here, the process that enters main () is the parent process, which executes the system call fork () on line 8th to create a process, that is, to copy a child process. After the child process is copied, it accepts the kernel dispatch as if it were the parent process, and has the same return address. So the parent and child processes return to the same point when they are scheduled to continue running and return from inside and space. More than 1000 of the ladies have only one process to execute, and from that point there are two processes executing. The copied process completely inherits all the resources and attributes of the parent process, but there are some differences.
First, the subprocess has a process number PID that differs from the parent process, and there are several fields in the task_struct of the child process that describe who is its father.
Second, they return from fork () with a different return value. When a child process returns from fork (), its return value is 0, and the return value of the parent process from fork () is indeed the PID of the child process, which is unlikely to be 0.
In this procedure, the IF statement is distinguished from the parent-child process. Then 10–12 (No 13 lines, for the next reason) the line belongs to the child process, and the 第16-19 line belongs to the parent process, each of which executes its own route. In this process, we choose to have the parent process stop waiting, so the parent process calls WAIT4 (), and the child process executes "/bin/echo" through Execve (). The child process will not execute the 13th line after Echo executes, but instead "the mighty one goes and no longer returns". This is because there must be an exit () call in Echo so that the child process ends its life. The call to exit () is a must for each executable image, although we do not call it in this program, but instead return from main () with the return statement, but GCC is automatically added when compiling and connecting, so every program cannot escape this.
Reference:
Maudeca, Hu Himing, "Linux kernel source code Scenario Analysis" (volume)
Creation, execution, and extinction of Linux processes