Process Control (Linux)

process creation

Introduction to the fork function

The function of the fork function is to create a child process in an existing process

#include <unistd.h>
pid_t fork(void);

Return value: creation failure returns -1; creation is successful, the child process returns 0, and the parent process returns the process id of the child process; a simple analogy can be made: the father can have multiple children, but the child has only one father, so after the process is created Need to give the child's idto the father, and the child process getpid()can get its own as long as it needsid

insert image description here
insert image description here

After the process calls the fork function, the operating system will allocate a new memory block and kernel data structure to the child process; copy part of the data structure content of the parent process to the child process; add the child process to the process list

fork function return value

Why forkdoes a function have two return values? And why after returning, assign the id of the child process to the parent process, and assign a value of 0 to the child process? Why can the same return value be if elseestablished at the same time?
Next, take a closer look at the function

First, the user uses forkthe function, and the operating system starts to call the function to complete the corresponding task

insert image description here

When the function fork()is ready return pid;, the core code has been executed, the child process has also been created, and is ready to be scheduled in the operating queue of the operating system; therefore, before execution, the parent and child processes have been split, and the statements return pid;can be executed separately return pid;; the essence of return It is writing, the child process or the parent process returns first, and whoever writes into the id first, because of copy-time-writing, the same id will have two different contents, and match according to different contents and judgment if elsestatements

common usage of fork

  1. The parent process wants to copy itself so that the parent and child processes execute different code segments at the same time
  2. The parent process wants the child process to execute a different program

The reason for the failure of the fork call

  1. Too many processes in the system
  2. The number of real user processes exceeds the limit

process terminated

process exit scenario

  1. The code runs and the result is correct
  2. The code runs to completion with an error
  3. The code terminates abnormally

Common ways to exit a process

First introduce the exit code, so far, the code written will be added at the end return 0; why must it be the number 0 instead of other numbers? ? ?
When the process exits, it will return the corresponding exit code, indicating whether the result of the process execution is correct; generally speaking, the exit code must have a corresponding text description
Exit code: 0 means the program is running normally;! 0 Specific numbers indicate different errors

The program terminates normally,
you can echo $view
insert image description here

  1. return return

  2. Calling the exit
    insert image description hereinsert image description here
    program does not print immediately hello world, but after two seconds; and the exit code is also exit(1)consistent with the one set in the program

  3. Calling the _exit
    insert image description here
    insert image description here
    program does not print at all hello world, and the exit code is still the same

The reasons are as follows:
exit terminates the process and actively refreshes the buffer
_eixt terminates the process without refreshing the buffer

The difference between the two: exit is a library function; _exit is a system call

insert image description here

return function

returnIt is a more common way to exit the process, and execution return nis equivalent to executionexit(n)

process waiting

Process waiting necessity

  1. If the child process exits, the parent process has been unable to obtain its status, which will cause the child process to become a zombie state, resulting in memory leaks
  2. There is nothing the OS can do if the process becomes a zombie
  3. The purpose of the parent process to create the child process is to complete the task, so it is necessary to know whether the child process is running, whether the result is correct or not, and whether it exits normally
  4. The parent process reclaims the resources of the child process and obtains the exit information of the child process by means of process waiting

Get subprocess status

How the process waits

  1. wait/waitpid, each has a statusparameter , which is an output parameter that is populated by the operating system
  2. If NULL is passed, it means that the exit status information of the child process is not concerned (the child process is blocked)
  3. The operating system will feed back the exit information of the child process to the parent process according to this parameter
  4. statusIt cannot be simply viewed as a whole. The bitmap is as follows: the signal equal to 0 means normal exit, and the exit status is the exit code (the bitmap will be studied in detail later in the study)

status&0x7FProcess exit information; status >>8)&0xFFget process exit status

insert image description here

wait method

#include<sys/types.h>
#include<sys/wait.h>

pid_t wait(int*status);

Return value: If successful, return the id of the waiting process; if failed, return -1
Parameter: output parameter, get the exit status of the child process, if you don't care, you can set it to NULL;

insert image description here
insert image description here
insert image description here
The child process has been running in the first ten seconds, and the status is S+; between ten and fifteen seconds, the child process terminates and is in a zombie process Z+; after fifteen seconds, the parent process waitreclaims the resources of the child process

waitpid method

#include<sys/types.h>
#include<sys/wait.h>
pid_t waitpid(pid_t pid,int*status,int options);

Return value: If successful, return the id of the child process; if the option is set WNOHANG, but waitpidthere is no exited child process to collect, then return 0; if it fails, return -1, then errno will be set to the corresponding value to wrong indication

Parameters:
pid: child process id

status: WIFEXITED: If the child process is terminated normally, it is true, check whether the process exits normally; WEXITSTATUS: If WIFEXIT is non-zero, extract the process exit code, check the exit code of the process

options:
0 defaults to the blocking state; WNOHANG(non-blocking): If the subprocess specified by pid has not ended, waitpdthe function returns 0 without waiting; if the process ends normally, the id of the subprocess is returned

insert image description here
insert image description here

statusThe process of obtaining child process information: after the child process exits, the exit status and termination information are saved to the PCB; the parent process system call, waitpidby statusobtaining the exit status of the child process, terminates the information

insert image description here

Get status by macro

insert image description here
insert image description here

Blocking vs non-blocking

Blocking: When the parent process is waiting to obtain the child process resources, if the child process has not exited, the parent process has been waiting for it to exit; non-blocking: when the parent process is waiting to obtain the child process resources, if the child process has not exited, the parent process You can execute other programs without waiting for the child process all the time, and take polling

pid_t waitpid(pid_t pid,int*status,int options);Among them, optionwhen the value is 0, it represents the blocking state; optionwhenWNOHANG the value is 0, it represents the non-blocking state

The blocking state has been shown above, and the non-blocking acquisition of child process resources will be shown next
insert image description here
insert image description here

waitpidReturn value: equal to zero, the call is successful, but the child process does not exit; greater than zero, the call is successful and the child process also exits; less than zero, the call fails

  1. If the child process has already exited, wait/waitpidwhen called, it will return immediately, release resources, and obtain the exit information of the child process
  2. If called at any time wait/waitpid, the child process exists and is running normally, the process may block
  3. If the child process does not exist, an error is returned immediately

process program replacement

Replacement principle

After forkthe child process is created to execute the program, the child process often needs to call a execfunction to execute another program, that is, a program different from the parent process; when the process calls a function, the execcreated child process will specify The program is loaded into the memory and executed ; the call execdoes not create a new process, so execthe id of the process does not change before and after the call

The essence of program replacement: load the code and data of the specified program to the specified location, and do not overwrite the data and code of the parent process

insert image description here

replace function

execThere are six kinds of functions execstarting with

int execl(const char *path, const char *arg, ...);

l: list, pass execlin

First execute the program, you need to find the program first, and then execute it, including how to execute it,
pathindicating the path of the program; argindicating how to execute the program, similar to command line parameters ; ...indicating a list of variable parameters, the last parameter must beNULL

insert image description here
insert image description here

In the running result, only the first one is printed printf, but the second one is not printed, why?
Because printfis also a code, and the second one is execlafter the replacement function, when the replacement function is executed, the original code has been completely covered, and the new program code is started and executed, so the second one printfcannot executed

int execlp(const char *file, const char *arg, ...);

p:path, you can automatically find the path where the program is located, just enter the program to be executed

insert image description here
![Insert picture description here](https://img-blog.csdnimg.cn/7dda163e822444408419cc2419f2ecc4.png

The first lsrepresents the program to be executed; the second lsrepresents how to execute

int execv(const char *path, char *const argv[]);

v: vector, you can put all executable parameters into an array and pass them uniformly instead of using variable parameters

insert image description here

insert image description here

int execvp(const char *file, char *const argv[]);

Directly enter the program to be executed and how to execute it

insert image description here
insert image description here

So far, the system commands have been executed. Let's try to execute the program I wrote

insert image description here

Program written by myself:

insert image description here

operation result:
insert image description here

According to the running results, the call is very successful; so you can use the replacement function to call the program in any language

int execle(const char *path, const char *arg,
                    ..., char * const envp[]);

e: Custom environment variables

Try first without adding custom environment variables

insert image description here
insert image description here
insert image description here

The above is a simple way to obtain the environment variables in the two systems; what should I do if I want to customize the environment variables? ? ?

First introduce a function: putenv
insert image description here
add an environment variable to the environenvironment variable table pointed to in the system
. The operation of custom environment variables is as follows:
insert image description here
insert image description here
insert image description here

execleEnvironment variables can be obtained. Similarly, the above replacement functions can also obtain environment variables. There are environment variable parameters in the virtual address space, and child processes can obtain environment variables through the address space.

execleThe argument list for is very similar to the command-line arguments for mianthe function

insert image description here

mainIt is also a function, which must be called and passed as parameters, and execlthe program is loaded into the memory; so the order of program execution is: first load, then execute

The essence of the program replacement function is to load the program into the memory, and the loading work is done by the Linux exec* loader

function explanation

  1. If the replacement function is called successfully, the new program will be loaded and executed from the startup code without returning
  2. Returns -1 if the replacement fails
  3. Replacement function, only failure return value, no success return value

Guess you like

Origin blog.csdn.net/qq_68006585/article/details/129845290