Linux系统编程(进程)———进程退出

Posted 橙子果果

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux系统编程(进程)———进程退出相关的知识,希望对你有一定的参考价值。

进程退出

正常退出
1.Main函数调用return
2.进程可以调用exit(),标准c库
3.进程可以调用_exit()或着 _Exit(),属于系统调用

补充:
1.进程最后一个线程返回
2.最后一个线程调用prhread_exit

异常退出
1.调用abort
2.当进程收到某些信号时,如ctrl+c
3.最后一个线程对取消(cancella)请求做出响应

不管进程如何终止,最后都会执行内核中的同一段代码。这段代码为相应进程关闭所有打开描述符,释放它所使用的存储器等。

对于上述任意一种终止情形,我们都希望终止进程能够通知其父进程它是如何终止的。对于三个终止函数(exit、_exit和_Exit),实现这一点的方法是,将其退出状态(exit status)作为参数传递给函数。在异常终止情况下,内核(不是进程本身)产生一个指示其异常终止原因的终止状态(termination status)。在任意一种情况下,该终止进程的父进程都能用wait或waitpid函数取得其终止状态。


等待子进程退出

为什么要等待子进程退出?
创建子进程的目的是让子进程去干活,干活到底是干完了还是没有干完。
干完了可以根据子进程的退出码查看工作的完成情况。
没干完是发生什么情况导致进程退出。

1、子进程退出状态不被收集,变成僵死进程。
2、父进程等待子进程退出,并收集子进程的退出状态。

收集子进程的退出状态 wait函数

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

       pid_t wait(int *status);

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

       int waitid(idtype_t idtype, id_t id, siginfo_t *infop, int options);

wait都有一个状态码
status参数是一个整型数指针
非空:子进程退出状态放在它所指向的地址中。
空:不关心退出状态


这里先运行子进程3次,然后结束子进程,回传数字5,回传的数被收集,最后通过WEXITSTATUS来解析这个数。

正常退出,调用WEXITSTATUS(status)来检测子进程回传的数5.

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
int main()
{
        pid_t pid;

        int cnt = 0;
        int status = 10;
        pid = fork();

        if(pid>0)
        {
                wait(&status);
                printf("child quit,child status = %d\\n",WEXITSTATUS(status));
                while(1){
                printf("this is father print,pid = %d\\n",getpid());
                sleep(1);
                printf("cnt = %d\\n",cnt);
                }
        }
        else if(pid == 0)
        {
                while(1){
                printf("this is child print,pid = %d\\n",getpid());
                sleep(1);
                cnt++;
                if(cnt == 3){
                        exit(5);
                        }
                }
        }

        return 0;
}


孤儿进程

父进程如果不等待子进程退出,在子进程之前就结束了自己的“生命”,此时子进程叫做孤儿进程

Linux避免系统存在过多的孤儿进程,init进程收留孤儿进程,变成孤儿进程的父进程。

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
int main()
{
        pid_t pid;

        int cnt = 0;
        pid = fork();

        if(pid>0)
        {
                printf("this is father print,pid = %d\\n",getpid());
        }
        else if(pid == 0)
        {
                while(1){
                printf("this is child print,pid = %d,father pid = %d\\n",getpid(),getppid());
                sleep(1);
                cnt++;
                if(cnt == 5){
                        exit(0);
                        }
                }
        }
                
        return 0;
}   


这里父进程子进程一起运行,父进程只运行一次。
第一次子进程输出父进程的pid,但父进程结束后,子进程输出的父进程的pid为1,被init进程收留。

以上是关于Linux系统编程(进程)———进程退出的主要内容,如果未能解决你的问题,请参考以下文章

Linux 编程之进程篇:task_struct进程创建和退出

Linux系统编程(进程)———进程退出

Linux系统编程(进程)———进程退出

Linux系统编程(进程)———进程退出

Linux系统编程(进程)———进程退出

Linux系统编程篇--进程控制篇