标签:编译 执行 直接 inux 操作文件 方式 return class fun
每一个启动进程都有一个 task_struct 结构,这是个结构体,命名为进程表项(或 进程控制块)如下:
启动一个程序操作文件的过程如下:进程启动创建一个 task_struct 进程表项,进程表项中有一个成员指向文件描述符表
进程的启动和退出如下:
main 运行的时候,内核会帮忙启动一个例程(C start template),启动例程会帮忙启动 main 函数,并帮忙收集命令行参数,环境参数等等,调用结束以后,main 返回给启动例程。
若是调用 exit() 函数,就不会返回给main 函数或其他函数了。exit() 直接调用内核所提供的系统调用退出函数。
atexit 函数为注册退出函数。
启动例程的作用
正常终止
异常终止
进程返回
进程终止方式区别
1 #include <stdlib.h> 2 int atexit (void (*function)(void));
1 #include <stdio.h> 2 #include <unistd.h> 3 #include <string.h> 4 #include <stdlib.h> 5 #include <fcntl.h> 6 7 //定义进程的终止函数 8 void term_fun1(void) 9 { 10 printf("first term function\n"); 11 } 12 13 void term_fun2(void) 14 { 15 printf("second term function\n"); 16 } 17 18 void term_fun3(void) 19 { 20 printf("third term function\n"); 21 } 22 23 int main(int argc, char *argv[]) 24 { 25 if(argc < 3) { 26 fprintf(stderr, "usage: %s file [exit | _exit | return]\n", argv[0]); 27 exit(1); 28 } 29 30 //向进程登记终止函数 31 atexit(term_fun1); 32 atexit(term_fun2); 33 atexit(term_fun3); 34 35 FILE *fp = fopen(argv[1], "w+"); 36 fprintf(fp, "hello world"); 37 38 if(!strcmp(argv[2], "exit")) { 39 exit(0);//标准C 的库函数 40 } else if(!strcmp(argv[2], "_exit")) { 41 _exit(0);//系统调用 42 } else if(!strcmp(argv[2], "return")) { 43 return 0; 44 } else { 45 fprintf(stderr, "usage: %s file [exit | _exit | return]\n", argv[0]); 46 } 47 48 exit(0); 49 }
结果是前两种可以正常运行,并且对文件可以正常写入,但是第三种方式无输出,且文件创建了,但没有写入。
而且可以看见终止方式是以栈的方式进行调用的。
可以知道选用 _EXIT和_exit 系统调用的时候,不会进行调用。之所以没有输出,代码中向文件写入数据的时候,表现为全缓存,这些数据可能还存放在缓存中,并没有从缓存中释放出来。带代码中加入 fclose 函数或程序终止后,会自动清缓存,但是系统调用 _exit 和 _EXIT 不会自动刷新缓存。
标签:编译 执行 直接 inux 操作文件 方式 return class fun
原文地址:https://www.cnblogs.com/kele-dad/p/9108243.html