About process control

Keywords: C++ Unix Back-end server

Process control

Create process

fork

//Create child process

pid_t fork(void);

//Success: the parent process returns the PID of the child process, and the child process returns 0; Failure: Return - 1, set errno value

The parent-child process who preempts the CPU time slice will execute first

Global variables cannot be shared between parent and child processes, although the printed addresses are the same because they are virtual addresses

If the parent-child process only reads global variables, the parent-child process has only one copy in memory and belongs to sharing

If any process in the parent-child process modifies the variable, it will copy a copy in memory, then modify it on the copy, and map it back after modification

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<unistd.h>

int main()
{
    printf("before fork,pid:[%d]\n",getpid());
    //Create child process
    pid_t pid = fork();

    if(pid<0)
    {
        perror("fork error");
        return -1;
    }
    else if(pid>0)
    {
        printf("father:pid==[%d]\n",getpid());
        sleep(1);
    }
    else if(pid==0)
    {
        printf("child:pid==[%d]\n",getpid());
    }
    printf("after fork,pid:[%d]\n",getpid());
    return 0;
}

ps and kill

ps aux | grep "xxx"
ps ajx | grep "xxx"

//-a: (all) processes of all users in the current system
//-u: View the process owner and other information
//-x: Display processes without control terminal -- processes that cannot interact with users [input, output]
//-j: List information related to job control

kill -l 
//Check what signals the system has

kill -9 pid 
//Kill a thread

getpid and getppid

//Get the PID of the current process
pid_t getpid(void);

//Get the PID of the parent process of the current process
pid_t getppid(void);

Loop to create n child processes

//Loop to create n child processes
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<unistd.h>

int main()
{
    int i=0;
    for(i=0;i<3;i++)
    {
        //Create child process
        pid_t pid = fork();

        if(pid<0)
        {
          perror("fork error");
          return -1;
        }
        else if(pid>0)
        {
            printf("father:pid==[%d]\n",getpid());
            sleep(1);
        }
        else if(pid==0)
        {
            printf("The first%d Child processes, child:pid==[%d]\n",i+1,getpid());
            break;
        }
    }

    return 0;
}

exec function family

Sometimes it is necessary to execute other commands or user-defined applications in a process. At this time, the functions in the exec function family are used

Generally, the method is to call fork in the parent process to create the first child process, and then call exec function in the child process

execl

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

//Path: the absolute path of the program to execute
//Parameter arg: the required parameter of the program to be executed
//arg: placeholder, usually write the name of the application
//arg: the parameter of the command
//After parameter writing: NULL

//If it is successful, it will not return and the code behind the exec function will not be executed; If it fails, the code after execl will be executed, and the error reason can be printed with perror
//execl function generally executes the program written by itself

execlp

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

//file: the name of the command to execute. Search for the command according to the PATH environment variable
//arg: occupied
//arg: the parameter of the command
//After parameter writing: NULL
//If it is successful, it will not return and the code behind the exec function will not be executed; If it fails, the code after exec will be executed, and the error reason can be printed with perror
//The execlp function is generally used to execute the program or command of the system
//Can global variables be shared between parent and child processes
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<fcntl.h>
#include<sys/types.h>
#include<unistd.h>
#include<sys/stat.h>

int main()
{
    //Create a child process
    pid_t pid=fork();
    
    if(pid<0)
    {
        perror("fork error");
        return -1;
    }
    else if(pid>0)
    {
        printf("father\n");
        sleep(2);
    }
    else if(pid==0)
    {
        printf("child\n");
        execl("./test","test","hello","dd",NULL);
        perror("execl error");
    }
    return 0;s
}

Process recycling

When a process exits, the process can recover its own user area resources, but cannot recover the PCB resources in the kernel space. Its parent process must call the wait or waitpid function to recover the child process, so as to avoid the waste of system resources

Orphan process

If parent process of the a child process has died and child process is still alive, process becomes an orphan process

In order to ensure that each process has a parent process, the orphan process will be adopted by the init process. The init process becomes the adoptive parent process of the orphan process. When the orphan process exits, the init process completes the recycling of the orphan process

Zombie process

If the child process dies and the parent process is still alive, but the parent process does not call the wait or waitpid function to recycle the child process, the child process becomes a zombie process

How to solve the zombie process

  • Since the zombie process is a dead process, you cannot kill it with the kill command
  • Zombie processes can be eliminated by killing their parent processes. After killing its parent process, the zombie process will be adopted by the init process, which will complete the recovery of the zombie process

Process recycling function

wait

pid_t wait(int *status);
//Block and wait for the child process to exit 
//Reclaim child process residual resources 
//Get child process end status (exit reason)

//Success: the ID of the child process cleaned up; Failed: - 1 (no child process)

//Status parameter: exit status of child process -- outgoing parameter
//Disabled (status): non-zero → the process ends normally
//WEXITSTATUS(status): get the process exit status 
//Wifsignled (status): non-0 → abnormal termination of process
//WTERMSIG(status): get the signal number of process termination
//The parent process calls the wait function to complete the recycling of the child process
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<fcntl.h>
#include<sys/types.h>
#include<unistd.h>
#include<sys/stat.h>
#include<sys/wait.h>

int main()
{
    pid_t pid=fork();
    
    if(pid<0)
    {
        perror("fork error");
        return -1;
    }
    else if(pid>0)
    {
        printf("father:pid=[%d],fpid=[%d]\n",getpid(),getppid());
        int status;
        pid_t wpid=wait(&status);
        printf("wpid==[%d]\n",wpid);
        if(WIFEXITED(status))//Normal exit
        {
            printf("child normal exit,status==[%d]\n",WEXITSTATUS(status));
        }
        else if(WIFSIGNALED(status))//Killed by the signal
        {
            printf("child killed by signal,signo==[%d]\n",WTERMSIG(status));
        }
    }
    else if(pid==0)
    {
        printf("child:pid=[%d],fpid=[%d]\n",getpid(),getppid());
        sleep(5);
        return 9;
    }

    return 0;
}

waitpid

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

//Same as wait function

//pid: 
//pid = -1 wait for any child process. Equivalent to wait
//PID > 0 waits for a child process whose process PID is equal to PID.
//pid = 0 wait for any child process whose process group ID is the same as the current process, that is, any process in the same process group as the process calling waitpid() function
//pid < - 1 waits for any child process whose group ID is equal to the absolute value of pid. (applicable to child processes in other groups)
//Status: the exit status of the child process. The usage is the same as that of the wait function
//options: set to WNOHANG, the function is non blocking, set to 0, the function is blocking

//Function return value
//>0: returns the recycled child process ID;
//-1: No child process
//=0: parameter 3 is WNOHANG and the child process is running

Posted by kapishi on Wed, 24 Nov 2021 11:54:04 -0800