Linux Process Control: process information query, process creation and killing, process replacement, zombie process

Keywords: Linux

Process control

Processes are the basic unit for managing transactions
The process has its own independent processing environment (such as environment variables, the directory in which the program is running, which user is running the program, etc.) and system resources (such as processor CPU occupancy, memory, I/O devices, data and programs).

Process control block PCB

The process control block of the Linux kernel is task_struct structure
At: / usr / SRC / Linux headers XXX / include / Linux / sched. H

PSB code is very long. Here are some information.

  1. Process id: each process in the system has a unique id, which is used in C language_ T is actually a nonnegative integer.
  2. Process status: ready, running, suspended, stopped, etc.
  3. Some CPU registers that need to be saved and restored during process switching.
  4. Information describing the virtual address space.
  5. Information describing the control terminal.
  6. Current Working Directory.
  7. umask mask.
  8. The file descriptor table contains many pointers to the file structure.
  9. Signal related information.
  10. User id and group id.
  11. Session s and process groups.
  12. The maximum Resource Limit that a process can use.

Process status

In the three state model, the process state is divided into three basic states: running state, ready state and blocking state.
In the five state model, processes are divided into new state, termination state, running state, ready state and blocking state.

①TASK_RUNNING: the process is being executed by the CPU. When a process is just created, it will be in TASK_RUNNABLE indicates that it is ready and waiting to be scheduled.
②TASK_INTERRUPTIBLE: the process is sleeping (that is, it is blocked) waiting for certain conditions to be met. Once these conditions are met, the kernel sets the process state to run. The process in this state will also be awakened in advance because it receives a signal, such as a task_ A process in intermittent state sends a SIGKILL signal. The process will first wake up (enter TASK_RUNNABLE state), and then exit (change to TASK_ZOMBIE state) in response to the SIGKILL signal. It will not start from task_ The status of intermittent exits directly.
③TASK_UNINTERRUPTIBLE: a process that is waiting to be awakened when resources are met, but cannot be awakened by other processes through signals or interrupts. Since it does not accept any external signals, it is impossible to kill these processes in this state with kill. And task_ The significance of the unique state is that some processing processes of the kernel cannot be interrupted. If you respond to asynchronous signals, a process for processing asynchronous signals will be inserted into the execution process of the program, and the original process will be interrupted, which may make some devices fall into an uncontrollable state. In task_ The uninterruptible state is usually very short, and it is almost impossible to capture it through the ps command.
④TASK_ZOMBIE (dead): indicates that the process has ended, but its parent process has not called wait4 or waitpid() to release the process descriptor. In order for the parent process to know its message, the process descriptor of the child process is still retained. Once the parent process calls wait4(), the process descriptor is released.
⑤TASK_STOPPED: the process stops execution. When the process receives SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU and other signals. In addition, any signal received during debugging will put the process into this state. When SIGCONT signal is received, it will return to task again_ RUNNABLE.

Meaning of parameters in stat:

parametermeaning
DNon interruptible (normally IO)
RA process that is running or in the queue
S (in words)In sleep state
TStopped or tracked
ZZombie process
WEnter memory swap (invalid since kernel 2.6)
XDead process
<High priority
NLow priority
sInclude child processes
+Process group in foreground

View process information

ps

Common combinations:

ps aux
ps ef
ps -a

See the detailed status of the process and common options (you can not add "-" before the options)

optionmeaning
-aDisplays all processes on the terminal, including those of other users
-uDisplays the detailed status of the process
-xDisplays processes without control terminals
-wThe display is widened to show more information
-rShow only running processes
-jList information related to job control

top

The top command is used to dynamically display running processes.
When using the top command, add - d to specify the time interval for displaying information updates

Keymeaning
MSort according to memory usage
PSort by CPU share
TSort according to the running time of the process
UYou can filter processes based on the user name you enter later
KThe process can be killed according to the PID entered later.
qsign out
hGet help

Kill process

kill

Specify the process ID

kill [-signal] pid

The signal value ranges from 0 to 15, where 9 is absolute termination

killall

Specify the process name

killall [-signal] pname

Process number & a function to query the process number

Process number (PID): non negative integer
Parent process number (PPID):
Process group number (PGID): the process group can receive various signals from the same terminal. By default, the current process number will be regarded as the current process group number

getpid()

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

pid_t getpid(void);
Function:
    Get this process number( PID)
Parameters:
    nothing
 Return value:
    This process number

getppid()

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

pid_t getppid(void);
Function:
    Gets the parent process number of the process calling this function( PPID)
Parameters:
    nothing
 Return value:
    The parent process number of the process calling this function( PPID)

getpgid()

#include <sys/types.h>
#include <unistd.h>
​
pid_t getpgid(pid_t pid);
Function:
    Get process group number( PGID)
Parameters:
    pid: Process number
 Return value:
    When the parameter is 0, the current process group number is returned; otherwise, the process group number of the process specified by the parameter is returned

Process creation

fork()

Called once but returned twice, the child process returns a value of 0 and the parent process returns the child process ID

#include <sys/types.h>
#include <unistd.h>
​
pid_t fork(void);
Function:
    It is used to create a new process from an existing process. The new process is called a child process and the original process is called a parent process.
Parameters:
    nothing
 Return value:
    Success: 0 is returned in the child process, and the child process is returned in the parent process ID. pid_t,Is an integer.
    Failed: Return-1. 
    The two main reasons for failure are:
        1)The current number of processes has reached the upper limit specified by the system errno The value of is set to EAGAIN. 
        2)The system is out of memory, and errno The value of is set to ENOMEM. 

Difference between child process and parent process information after fork

The address spaces of parent and child processes are independent
Linux fork() uses copy - on - write Implementation. At this time, the kernel does not copy the address space of the whole process, but allows the parent and child processes to share the same address space. The address space is copied only when writing is required, so that each process has its own address space. That is, the resource is copied only when writing is required. Before that, it is shared only in a read-only manner.

Note: after fork, the parent and child processes share files. The file descriptor of the child process generated by fork is the same as that of the parent process, points to the same file table, the reference count increases, and the offset pointer of the shared file.

The child process obtained by using the fork() function is a replica of the parent process. It inherits the address space of the whole process from the parent process, including process context (static description of the whole process of process execution activities), process stack, open file descriptor, signal control setting, process priority, process group number, etc.
Only its process number, timer, etc. (only a small amount of information) are unique to a child process

fork extension

Cycle n times, output 2N-1 (1 + 2 + 4 +... + 2n-1) sub processes, and print 2 * (1 + 2 + 4 +... + 2n) times

for(i=0;i<n;i++){  
   pid_t fpid=fork();  
   if(fpid==0)  
       printf("%d child  %4d %4d %4d/n",i,getppid(),getpid(),fpid);  
   else  
       printf("%d parent %4d %4d %4d/n",i,getppid(),getpid(),fpid);  
}  

process exit

This process exits

The functions and usage of exit() and exit() are the same. exit() belongs to the standard library function and exit() belongs to the system call function

exit() & _exit()

#include <stdlib.h>
void exit(int status);
​
#include <unistd.h>
void _exit(int status);
Function:
    End the process calling this function.
Parameters:
    status: The parameter returned to the parent process (the lower 8 bits are valid). Fill in the parameter as needed.
Return value:
    nothing

Wait for the child process to exit

When each process exits, the kernel releases all the resources of the process, including open files, occupied memory, etc. However, certain information is still reserved for it, which mainly refers to the information of the process control block PCB (including process number, exit status, running time, etc.).

The parent process can get its exit status by calling wait or waitpid, and completely clear the process.

The functions of wait() and waitpid() functions are the same. The difference is that the wait() function blocks, waitpid() can be set not to block, and waitpid() can also specify which child process to wait for to end.
Note: a wait or waitpid call can only clean up one child process

wait()

#include <sys/types.h>
#include <sys/wait.h>
​
pid_t wait(int *status);
Function:
    Wait for any child process to end. If any child process ends, this function will recycle the resources of the child process.
Parameters:
    status : Status information when the process exits.
Return value:
    Success: the process number of the child process has ended
    Failed: -1

The process calling the wait() function will hang (block) until one of its child processes exits or receives a signal that cannot be ignored (equivalent to continuing execution). If the calling process has no child process or the child process has ended, the function returns immediately;
status exit information contains multiple fields in an int. if you directly use meaningless, you need to use macro functions to get each field.

Macro function for parsing status field
  1. WIFEXITED(status)
    Is not 0 → the process ends normally
    WEXITSTATUS(status)
    If the above macro is true, use this macro → to obtain the process exit status (exit parameter)
  2. WIFSIGNALED(status)
    Is not 0 → process terminated abnormally
    WTERMSIG(status)
    If the above macro is true, use this macro → to obtain the number of the signal that terminates the process.
  3. WIFSTOPPED(status)
    Is not 0 → the process is paused
    WSTOPSIG(status)
    If the above macro is true, use this macro → to obtain the number of the signal that pauses the process.
    WIFCONTINUED(status)
    True → the process has resumed running after being paused

waitpid()

#include <sys/types.h>
#include <sys/wait.h>
​
pid_t waitpid(pid_t pid, int *status, int options);
Function:
    Wait for the child process to terminate. If the child process terminates, this function will recycle the resources of the child process.
​
Parameters:
    pid : parameter pid There are several types of values:
      pid > 0  Waiting process ID be equal to pid Child process of.
      pid = 0  Wait for any child process in the same process group. If the child process has joined another process group, waitpid Won't wait for it.
      pid = -1 Wait for any child process, at this time waitpid and wait It works the same.
      pid < -1 Wait for any child process in the specified process group, and the ID be equal to pid Absolute value of.
​
    status : Status information when the process exits. and wait() Same usage.
​
    options : options Some additional options are provided to control waitpid(). 
            0: with wait(),Block the parent process and wait for the child process to exit.
            WNOHANG: If there are no child processes that have ended, return immediately.
            WUNTRACED: If the child process is paused, this function returns immediately and ignores the end state of the child process. (because it involves some knowledge of tracking and debugging, and it is rarely used)
                 
Return value:
    waitpid() Return value ratio of wait() Slightly more complicated, there are three situations:
        1) When it returns normally, waitpid() Return the collected process number of the recycled child process;
        2) If options are set WNOHANG,While calling waitpid() If it is found that there are no exited child processes to wait, 0 is returned;
        3) If there is an error in the call, return-1,At this time errno It will be set to the corresponding value to indicate the error, such as when pid The corresponding child process does not exist, or the process exists, but it is not a child process of the calling process, waitpid() An error will be returned, and then errno Set to ECHILD;

Process replacement

exec function family

#include <unistd.h>
extern char **environ;
​
int execl(const char *path, const char *arg, .../* (char  *) NULL */);
int execlp(const char *file, const char *arg, ... /* (char  *) NULL */);
int execle(const char *path, const char *arg, .../*, (char *) NULL, char * const envp[] */);
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
int execvpe(const char *file, char *const argv[], char *const envp[]);
​
int execve(const char *filename, char *const argv[], char *const envp[]);

execve() is the system call, and other library functions are wrapped on this basis

The function of exec family is to execute an executable file inside the calling process. The process is completely replaced by a new program. Instead of creating a new process, it only replaces the body, data, heap and stack segments of the current process (process replacement)

The functions in the exec function family will not return after successful execution, so the code below the exec function family cannot be executed. Only when the call fails, it will return - 1. After the failure, it will be executed from the call point of the original program.

Instructions for exec function family

l(list)Parameter address list, ending with a null pointer
v(vector)The address of the pointer array containing the address of each parameter
p(path)Searches for executable files in the directory specified by the PATH environment variable
e(environment)The address of the pointer array that holds the string address of the environment variable

Zombie process

The process terminates, the parent process has not been recycled, and the child process residual resources (PCB) are stored in the kernel and become a Zombie process. If no one reclaims its process number, it will always be occupied, but the process number that the system can use is limited. Should be avoided.

Posted by akjackson1 on Tue, 12 Oct 2021 01:06:39 -0700