进程的正常结束
main函数中执行了return 结束进程
int main(...) { ... return x; // 该返回值可以被父进程接收 } // 等价于 int main(...) { ... exit(x) // 该返回值可以被父进程接收 }
调用标准C的exit函数 结束进程
#include <stdlib.h> void exit(int status); status:进程的结束状态码
-
该函数一旦调用就不会返回,其父进程通过wait\waitpid函数可以获取到status的低8位数据
-
进程正常退出前会先调用事先通过atexit\on_exit函数注册过的函数,然后冲刷并关闭所有处于打开状态下的标准I/O流
-
可以用 EXIT_SUCCESS和EXIT_FAILURE常量作为exit或return的结束状态码,表示进程是正常结束,还是出问题结束的
-
该函数底层调用了 _exit \ _Exit函数
#include <stdlib.h> int atexit(void (*function)(void)); funciton: 函数指针 进程退出前要执行该函数 int on_exit(void (*function)(int , void *), void *arg) funciton: 函数指针 第一个参数:来自return的n或者exit的参数 status 第二个参数,来自on_exit的arg参数 arg:任意类型指针
#include <stdio.h> #include <stdlib.h> #include <unistd.h> void atexit_fp(void) { printf("我就要死了...\n"); } void on_exit_fp(int s,void* p) { printf("我要结束了...status=%d 遗言%s\n",s,(char*)p); } int main(int argc,const char* argv[]) { // 注册遗言函数 // 谁后注册,谁先执行 atexit(atexit_fp); on_exit(on_exit_fp,"是它杀了我"); for(int i=0; i<3; i++) { printf("我是进程%u\n",getpid()); sleep(1); } exit(10); }
调用_exit / _Exit 函数结束进程:
#include <unistd.h> void _exit(int status); # 该函数有一个完全等价的标准C版本 #include <stdlib.h> void _Exit(int status);
-
该函数一旦调用就不会返回,其父进程通过wait\waitpid函数可以获取到status的低8位数据
-
在进程退出前,先关闭所有打开状态下的文件描述符,并把所有的子进程托付给孤儿院进程收养(init\upstart--user),并把当信号SIGCHLD(17)发送给其父进程
其它正常结束进程的方式:
-
进程的最后一个线程执行完毕,进程也结束
-
进程的最后一个线程调用pthread_exit函数,进程也结束