1.1. main函数的调用
a. 编译链接时的引导代码。操作系统下的应用程序其实在main执行前也需要先执行一段引导代码才能去执行main,我们写应用程序时不用考虑引导代码的问题,编译连接时(准确说是连接时)由链接器将编译器中事先准备好的引导代码给连接进去和我们的应用程序一起构成最终的可执行程序。
b. 运行时的加载器。加载器是操作系统中的程序,当我们去执行一个程序时(譬如./a.out,譬如代码中用exec族函数来运行)加载器负责将这个程序加载到内存中去执行这个程序。
c. 程序在编译连接时用链接器,运行时用加载器,这两个东西对程序运行原理非常重要
1.2. 进程如何结束
1.2.1. 在main(main函数由其父进程调用,故返回后进程就over)用return,一般原则是程序正常终止return 0,如果程序异常终止则return -1。
1.2.2. 一般终止进程(程序)应该使用exit或者_exit或者_Exit之一。
1.2.3. atexit注册进程终止处理函数
1.2.4. return、exit和_exit的区别:return和exit效果一样,都是会执行进程终止处理函数,但是用_exit终止进程时并不执行atexit注册的进程终止处理函数。
1.2.5. atexit注册多个进程终止处理函数,先注册的后执行(先进后出,和栈一样)
实例:
#include <stdio.h> #include <stdlib.h> #include <unistd.h> void func1(void) { printf("func1\n"); } void func2(void) { printf("func2\n"); } int main(void) { printf("hello world.\n"); // 当进程被正常终止时,系统会自动调用这里注册的func1执行 atexit(func2); atexit(func1); printf("my name is lilei hanmeimei\n"); //return 0; //exit(0); _exit(0); }