当前位置:网站首页>wait、waitpid

wait、waitpid

2022-04-23 20:46:00 baboon_ chen

One 、 Orphan process

  The parent process ends before the child process , Then the child process becomes an orphan process , The parent process of the child process becomes init process , Responsible for the recovery process of .


Example :

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

int main(void)
{
    
        pid_t pid = fork();
        if(pid > 0){
             //  Parent process output pid And sleep 2s sign out 
                printf("parent pid is %d\n", getpid());
                sleep(2);
        }
        else if(pid == 0){
       //  Subprocess cyclic printing pid and ppid
                for(int i=0;i<10;i++){
    
                        printf("my pid is %d, my ppid is %d\n", getpid(), getppid());
                        sleep(1);
                }
        }
        else {
    
                perror("fork");
                exit(1);
        }
        return 0;
}


Running results :

 Insert picture description here


Two 、 Zombie process

  Zombie process : Process termination , The parent process did not recycle , The child process remains PCB Stored in the kernel , Become a zombie (zombie) process .

  Zombie processes cannot be used kill kill , because kill Just used to terminate the process , The zombie process has been terminated . The right way is kill Drop its parent process , So the zombie process will be init Process management recycle .


Example :

/*  We keep the parent process looping , The subprocess prints out pid and ppid Quit after  */
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int main(void)
{
    
	pid_t pid = fork();
	if(pid > 0){
    
		while(1){
    
			printf("parent pid is %d\n", getpid());
			sleep(2);
		}
	}
	else if(pid == 0){
    
		printf("my pid is %d, my parent pid is %d\n", getpid(), getppid());
		sleep(1);
	}
	else {
    
		perror("fork");
		exit(1);
	}
	return 0;
}

result :

 Insert picture description here


3、 ... and 、wait

​   A process closes all file descriptors on termination , Free up memory allocated in user space , But its PCB Still keep . The kernel holds some information in it :
​      If it is a normal termination, the exit state is saved ;
​      In case of abnormal termination, the signal that causes the process to terminate is saved .

​   The parent of this process can call wait or waitpid Get this information , And then get rid of the process . We know that the exit state of a process can be in Shell Special variables are used in $? see , because Shell It's its parent process , When it ends Shell call wait or waitpid Get its exit status , At the same time, completely delete the process .


wait() The role of :

1、 Blocking waits for the child process to end .

2、 Recycle subprocess pcb resources .

3、 Get child process end state :

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

pid_t wait(int *status);

//	return
//	on success, returns the process ID of the terminated child; 
//	on error, -1 is returned.

// status  The status returned when the child process exits , Check the status information through the following macro function .
//	WIFEXITED(status)	 It's true  ->	 Subprocess exits normally .
//		WEXITSTATUS(status)	 When the child process exits normally , Get the exit value through this function .
//	WIFSIGNALED(status)	 It's true  ->	 Abnormal exit of subprocess , Terminated by a signal .
//		WTERMSIG(status)	 When the subprocess exits abnormally , Get the signal received when exiting through this function .

//	 Other macro functions :
//	WCOREDUMP(status)
//	WIFSTOPPED(status)
//		WSTOPSIG(status)
//	WIFCONTINUED(status)


Example :

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main()
{
        pid_t pid = fork();

        if (pid == 0)
        {
                printf("I am the child process, pid=%u, ppid=%u\n", getpid(), getppid());
                sleep(2);
                execl("./test", "test", NULL);
        }
        else if (pid > 0)
        {
                int status;
                pid_t wpid;
                wpid = wait(&status);
                if (wpid == -1)
                {
                        perror("wait error");
                        exit(-1);
                }
                if (WIFEXITED(status))
                {
                        printf("child exit with %d.\n",WEXITSTATUS(status));
                }
                if (WIFSIGNALED(status))
                {
                        printf("child exit with signal:%d \n", WTERMSIG(status));
                }

                printf("I am the parent process, pid=%u\n", getpid());
        }
        else
        {
                perror("fork error");
                exit(-1);
        }

        return 0;
}

test.c

#include <stdio.h>

int main()
{
    
        int a = 5;
        int b = a/0;

        return 25;
}

Output results :

I am the child process, pid=19092, ppid=19091
child exit with signal:8 
I am the parent process, pid=19091

test.c: Normal end

 #include <stdio.h>
 
 int main()
 {
    
     int a = 5;
     int b = a/1;
 
     return 25;
 }

Output results :

I am the child process, pid=19903, ppid=19902
child exit with 25.
I am the parent process, pid=19902

Note:

once wait()、waitpid() call , Recycle only one child process .


Four 、waitpid

  The functions and wait identical , But you can specify pid Process cleanup , You can wait for the child process to end without blocking ( Check whether the subprocess ends by polling ).

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

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

//  Parameters 1: pid > 0  Specify process id Recycling 
/* pid > 0  Specify process id Recycling  pid = -1  Reclaim any child process  (==wait) pid = 0  Reclaim any child processes in this group  pid < -1  Reclaim any child process of the process group , Such as -2, Recycle all process groups as 2 Any child process of . */

//  Parameters 2:status  Same as  wait()

//  Parameters 3:options
// 0:  Blocking recovery , Same as wait()
// WNOHANG:  Non blocking recovery ( Polling reclaim )

//  Return value :
//  success : pid 
//  Failure : -1
//  ginseng 3 Pass on WNOHANG, The subprocess has not ended yet : 0


Example : establish 5 Subprocess , And recycle

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>


int main()
{
    
        pid_t pid, wpid;
        int n = 5;
        int i;

        for (i=0; i < n; i++)
        {
    
                //  establish n Subprocess 
                pid = fork();
                if (pid == 0)
                {
    
                        break;
                }
        }

        if (n == i)
        {
    
                //  The parent process 
                do {
    
                        wpid = waitpid(-1, NULL, WNOHANG);
                        if (wpid > 0)
                        {
    
                                n--;
                                printf("recycle child process:%u\n", wpid);
                        }
                        sleep(1);
                } while(n > 0);

                while(1)
                {
    
                        printf("I am the parent process, pid:%u\n", getpid());
                        sleep(1);
                }
        }
        else
        {
    
                //  The subprocess waits for a period of time 
                printf("I am the %dth child process, pid=%u, ppid=%u\n", getpid(), getppid());
                sleep(i);
        }

        return 0;
}

版权声明
本文为[baboon_ chen]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/04/202204210546350960.html