Linux -> Process Termination and Waiting

Table of contents

1. Process termination scenario

1.1 Process exit code

1.2 Common ways to exit a process

 2. Process waiting

2.1 The necessity of process waiting

2.2 The way the process waits

wait() method

waitpid() method

options parameter

status parameter


1. Process termination scenario

Code completes with correct result
Code completes with incorrect result
Code terminates abnormally

         Process termination means that we usually understand that the process has exited, but how do we understand the above three sentences? What is the correct or incorrect result after the code runs? Do we need to debug by ourselves every time? Yes, or each one needs to debug the program results through the IO interface and then judge whether the program is correct? The answer is obviously no, and the following will give you the result.

1.1 Process exit code

        First of all, we have to understand a concept, judging whether the result of a code is correct after running is definitely not what we thought before, using printf, cout or debugging to judge whether the program is correct or not, because for computers As far as we are concerned, it is meaningless for us to judge whether it is correct, because it runs too fast. If other processes need the exit information of this process, will it wait for us to tell us an answer? Will not. So programming languages ​​​​appeared- process exit codes .

        When you see the process exit code for the first time, you may think that this is a very powerful and powerful thing, but it is not. We usually use it when practicing C language and C++, but everyone does not know what it is for. . as follows:

 int main()
 {
      return 0;                                                                                                                  
 } 

        The 0 in the above code is one of the process exit codes, which means that the program is executed correctly. Do you feel a little speechless? Friends, do you think it is what it is? Ha ha. But speechless is speechless, this knowledge point is a bridge for many knowledge points, and it still needs to be understood carefully.

       0 means that the result is correct after the program is executed, and the rest of the numbers indicate that the result is incorrect . Why? Just because the C language stipulates? If you don't tell me this stuff, who will understand? I give an example:

        If you talk to your girlfriend, your girlfriend asks you "do you love me", you say "0", then your girlfriend feels puzzled, and then asks you "Are you sick? Let me ask you What?", and then you went back to "3", your girlfriend was so angry, she thought you were playing tricks on her, and finally ran away in anger. Are you wronged? You have answered well, but she doesn't understand.

        The above story shows that I don't care who you are, if I ask you something, you have to answer in a way I know, otherwise I will get angry and kick you out. So for the computer, we are this girlfriend, and he needs to answer in a way we know, so there is a strerror function in the string.h library, which can express the information of our process exit code in text . as follows:

  1 #include<stdio.h>  
  2 #include<stdlib.h>  
  3 #include<sys/types.h>  
  4 #include<string.h>  
  5 #include<unistd.h>  
  6 
  7 int main()
  8 {
  9   int i = 0;
 10   for(i = 0;i<130;++i)
 11   {
 12     printf("我的进程退出码是:%d,退出信息是:%s\n",i,strerror(i));
 13   }
 14 
 15   return 0;
 16 }

         The above is part of the process exit code information, you can see that the exit information of 0 is Success, I am not lying. I believe that if you take a good look, you can see some information that you have seen when writing Linux, such as exit code 2 and exit code 13. I take the exit code as an example, as follows:

         did you see it? The knowledge is strung together. I just heard that Linux is written in C language before, but I don’t know how it is written, but do you feel it here?

1.2 Common ways to exit a process

1. Return from main
2. Call exit
3. _exit

         The meaning of process exit from main is to return through return. Note that only the return value of the main function is called process exit. The return of other functions just means that the function of this function is over and brings back a return value. Received The place where the return value is still the process.

        Our exit and _exit functions do not have this limitation. They can end the process in any function. The usage is as follows:

exit("exit code");

_exit("exit code");

        It seems that there is no difference between the exit function and the _exit function? 

        In most cases, there is no difference between these two functions, but there are still some differences, please look at the following figure first:

         The difference is that _exit is a system interface, and exit is a library function provided by the stdio.h library, and the _exit function is called internally by the exit function, and the exit function call has no _exit function violence, it will first execute the previously executed code The process will end after running, and _exit will exit the process directly, regardless of the data in the buffer, etc.

 int main()                                                                                                        
 {
      printf("hello world");
      exit(0);                                                                                                                                   }   

int main()

{

        printf("hello world");
        _exit(0);     
}

 exit();Run result:

 _exit() running result:

 2. Process waiting

        Process waiting generally occurs between parent and child processes. The parent process waits for the child process to finish running, and the parent process is executing its own code. It is generally useful for network communication connections.

2.1 The necessity of process waiting

1. If the child process exits, if the parent process ignores it, it may cause the problem of a 'zombie process', and then cause a memory leak.
2. In addition, once a process becomes a zombie, it is invulnerable, and the "kill without blinking" kill -9 can do nothing, because no one can kill a dead process.
3. Finally, we need to know how the tasks assigned by the parent process to the child process are completed. For example, whether the child process finishes running, whether the result is correct or not, or whether it exits normally.
4. The parent process reclaims the resources of the child process by means of process waiting, and obtains the exit information of the child process

         The above concepts have clearly explained the necessity of process waiting for us. Regarding the zombie process, the child process exits, but the parent process does not recycle its resources, that is, obtains the process exit information, then the process status of the child process will be Change to Z, and keep this state all the time, no one can kill it, it will always occupy system resources .

2.2 The way the process waits

wait() method

        wait() is a function in the sys/wait.h library, the function is declared as:

pid_t wait(int*status);

         The return value is the pid of the waiting process if it is correct, and -1 if it is incorrect. The status parameter is an output parameter. When we don’t care about the exit status of the child process, we can set it to NULL. as follows:

code:

  1 #include<stdio.h>
  2 #include<unistd.h>
  3 #include<sys/wait.h>
  4 #include<sys/types.h>
  5 #include<stdlib.h>
  6 
  7 void test1()
  8 {
  9   int cnt = 5;
 10   while(1)
 11   {
 12     printf("我是子进程,我还能活%dS\n",cnt);
 13     sleep(1);
 14     --cnt;
 15     if(cnt == 0)
 16       exit(110);
 17   }
 18 }
 19 
 20 
 21 int main()
 22 {
 23   pid_t id = fork();
 24   if(id == 0)
 25   {                                                                                                                          
 26     test1();
 27   }
 28   pid_t subid = wait(NULL);
 29   printf("我是父进程,我等待子进程%d完毕\n",subid);
 30 
 31   return 0;
 32 }

result:

         From the code, it can be seen that the printf statement of the parent process is executed after the child process is executed, which means that the parent process is indeed in a waiting state after using the wait function, and the information of the child process is also recycled, because wait returns the correct pid.

waitpid() method

        waitpid() is a function in the sys/types.h library and the sys/wait.h library, declared as:

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

Return value:
When returning normally, waitpid returns the process ID of the collected child process;
if the option WNOHANG is set, and waitpid finds that there is no exited child process to collect during the call, it returns 0;
 if an error occurs in the call, it returns -1, then errno will be set to the corresponding value to indicate the error;
parameter:
pid:
Pid=-1, wait for any child process. Equivalent to wait.
Pid > 0. Wait for a child process whose process ID is equal to pid.
status:
WIFEXITED(status): If it is the status returned by the normal termination of the child process, it is true (check whether the process exited normally)
WEXITSTATUS(status): If WIFEXITED is non-zero, extract the exit code of the child process. (Check the exit code of the process)
options:
WNOHANG: If the child process specified by pid has not ended, the waitpid() function returns 0 and does not wait. If it ends normally, the ID of the child process is returned.

        The use of this function is basically the same as that of the wait function, but I need to explain its parameters options and the status output parameters that both functions have.

options parameter

        When we input it as 0, the function of the function at this time is the process waiting mode, which is the mode in the above figure, but if we input it as WNOHANG, then the function of the function will become polling waiting, what Meaning, first look at the code:

    1 #include<stdio.h>
    2 #include<unistd.h>
    3 #include<sys/wait.h>
    4 #include<sys/types.h>
    5 #include<stdlib.h>
    6 
    7 void test1()
    8 {
    9   int cnt = 5;
   10   while(1)
   11   {
   12       printf("我是子进程,我还能活%dS\n",cnt);
   13     sleep(1);
   14     --cnt;
   15     if(cnt == 0)
   16       exit(110);
   17   }
   18 }
   19 
   20 
   21 int main()
   22 {
   23   pid_t id = fork();
   24   if(id == 0)
   25   {                                                                                                                        
   26     test1();
   27   }
   28   int status = 0;
   29   pid_t subid = waitpid(id,&status,WNOHANG);
   30   printf("我是父进程,我不想等子进程了,先运行了,之后在回收资源\n");
   31   return 0;
   32 }

         As can be seen from the figure above, we pass the WNOHANG parameter, the parent process does not wait until the child process is executed before executing the code, but runs its own code first, and the child process runs by itself. I will tell a story that everyone can probably understand.

        Xiao Ming and Xiao Fang are good friends, one day Xiao Ming wanted to invite Xiao Fang to go out to play together, and then he called Xiao Fang and asked her if she could go out now? Xiaofang said: Wait for me, I'm taking a shower, Xiaoming said: Okay, I'll wait for you, don't hang up the phone. Then the phone kept ringing, and 15 minutes later, Xiaofang said: I'm fine. Then hung up the phone, and Xiao Ming and Xiao Fang went out together. —————Process waiting

         Still Xiaoming and Xiaofang, also Xiaoming wants to invite Xiaofang to go out to play, Xiaofang is still taking a bath, Xiaoming calls and asks: Are you still taking a shower? Xiaofang said: Yes. Then the phone hung up, Xiao Ming washed his face, and asked after about a minute: Still washing? Xiaofang said: Yes. Such a cycle, until Xiaofang said that the washing was finished, she would not continue to call to ask questions. ————— Polling waiting

         The above two stories correspond to the way our process waits. Xiao Ming is the parent process, and Xiao Fang is the child process.

status parameter

         What is an output parameter? The output parameter means that we only need to pass an address to enter, and then other functions get this space, modify its value, and get this value in the original function.

        status is an integer variable, and it is also a bitmap, which means that it uses a variable to store the value of the process exit code and exception information. Its high 16 bits are not used, and the next high 8 bits are used to store the process exit code. The lower 7 bits are used to store exception information, and the 8th bit is used to store core dump information. as follows:

printf("I am the parent process, the exit code of the child process is %d, and the exception information is %d\n", (status>>8)&0xFF,status&0x7F);  

        This method is our bitmap, and the usage method is bit operation. 

        It is worth mentioning that when the child process has an error, then there will be no exit code, that is to say - the program has no exception -> whether the program is executed correctly .

n /= 0; error statement

         The program crashes, the child process does not run successfully, the exit code is 0, and the exception information is 8.


        The above is my full understanding of process termination and process waiting. Please support me a lot, thank you.

Guess you like

Origin blog.csdn.net/weixin_52345097/article/details/129274170