进程环境
来源:互联网 发布:ubuntu安装openssh 编辑:程序博客网 时间:2024/05/17 07:16
1. 首先通过下图了解C程序是如何启动和终止的。
1.C程序的启动:
当内核执行C程序时,(使用一个exec函数),在调用main之前先调用一个特殊的启动例程。启动例程从内核取得命令行参数和环境变量值,为调用main函数做还安排。
2.进程终止的方式:
正常终止:
(1).从main返回。
(2).调用exit
(3).调用_exit(#include<unistd.h>)或_Exit(#include<stdlib.h>)
(4).最后一个线程从其启动例程返回
(5).最后一个线程调用pthread_exit()
异常终止:
(6).调用abort()
(7).接到一个信号并终止(SIGKILL)
(8).最后一个线程对取消请求做出响应(pthread_cancle)
exit函数
#include <stdlib.h>
(1).void exit(int status);
(2).void _Exit(int status);
#include <unistd.h>
(3).void _exit(int status);
_exit和_Exit立即进入内核
exit先执行一些清理处理(刷新缓冲区或关闭文件)然后调用上述两个函数进入内核
exit:#include <stdio.h>#include <stdlib.h>Int main(void){printf(“I can be showing on the terminal by exit()”);//注意这里没有以’\n’来结尾exit(0);}
在这里终端打印了printf输出语句。
_exit:#include <stdio.h>#include <unistd.h>int main(void){printf("i can be showing on the terminal by exit()");_exit(0);}_Exit:#include <stdio.h>#include <stdlib.h>int main(void){printf("i can be showing on the terminal by exit()");_Exit(0);}这两种情况都没有打印出printf语句。这是因为_exit()和_Exit直接进入内核,不会考虑IO缓冲区是否还有数据。
3.atexit函数:
头文件:#include <stdlib.h>
函数声明:int atexit(void (*function)(void));
函数说明: atexit用来登记一个程序正常结束前调用的函数(终止处理程序)。当程序通过调
用 exit()或从 main 中返回时,参数 function 所指定的函数会先被调用,然后才真正由 exit()结束程序。
返回值:如果执行成功则返回0,否则返回-1.设置errno
其中atexit函数的参数是一个函数指针,此函数不需要任何参数,也没有返回值。
_exit调用这些函数的顺序与他们登记时候的顺序相反。同一函数如果登记多次,则也会被调用多次。
下面是一个atexit的例子:
#include <stdio.h>#include <stdlib.h>static void exit_1(void);static void exit_2(void);int main(void){if(atexit(exit_2) != 0){printf("cant register exit_2\n");}if(atexit(exit_1) != 0){printf("cant register exit_1\n");}if(atexit(exit_1) != 0){printf("cant register exit_1\n");}printf("main is done\n");return 0;}static void exit_1(void){printf("first exit_1 handle\n");}static void exit_2(void){printf("second exit_2 handle\n");}
4.命令行参数:
echo命令的简单实现:
#include <stdio.h>#include <stdlib.h>int main(int argc,char *argv[]){int i;/*for(i = 1; i < argc; i++){printf("%s\t",argv[i]);}*/for(i = 1; argv[i] != NULL; i++){printf("%s\t",argv[i]);}putchar('\n');exit(0);}
argv[argc]是一个空指针,所以可以将参数处理循环改写为
for(i = 1; argv[i] != NULL; i++)
5.环境表:
每个程序都会收到一张环境表。与参数表一样,环境表也是一个字符指针数组,其中一个指针包含一个以NULL结尾的C字符串的地址。全局变量environ包含了该指针数组的地址:
extern char **environ;
6.C程序的存储布局:
(1).正文段(代码段):这是CPU执行的机器指令的部分,也就是存储程序代码的区域。
(2).初始化数据段(数据段):包含了程序中需明确赋值的变量。一般是全局变量
(3).非初始化数据段:在程序开始之前,内核将此段中的变量初始化为0或空指针。一般是全局变量。
(4).栈:自动变量(传递给函数的参数(副本机制),返回值(副本机制),函数内部声明的局部变量)。
(5).堆:通常在堆中进行动态存储分配。一般由malloc/calloc/realloc函数开辟的内存区域。
7.存储器的分配:
三个用于存储空间动态分配的函数:
(1).malloc 分配指定的字节数的存储区,此存储区没有被初始化。
(2).calloc 为指定数量具有指定长度的对象分配存储空间。该区域每一位都被初始化为0.
(3).realloc: 更新以前分配区的长度。需要注意的是,realloc的最后一个参数指定的长度是存储区的新长度,而不是新,旧存储区的长度之差。
更详细的解释在APUE2-7.8
8.setjmp和longjmp函数:
这两个函数处理发生在深层嵌套函数调用中的出错情况很有用。
这两个函数类似于非局部的goto,它们在栈上跳过若干调用帧,返回到当前函数调用路径上的某一个函数中。(从某个函数跳转到另一个函数)。
Setjmp参数env(传出参数)的类型是一个特殊类型jmp_buf,某种形式的数组。其中存放了在调用longjmp时能够回复栈状态的所有信息。因为需要在不同的函数中引用env变量,所以一般将env变量定义为全局变量。
Longjmp 的第一个参数是在调用setjmp时所用的env,第二个参数将成为setjmp函数的返回值为非0值。
- 进程环境
- 进程环境
- 进程环境
- 进程环境
- 进程环境
- 进程环境
- 进程环境
- 进程环境
- 进程环境
- 进程环境
- 进程环境
- 进程环境
- 进程及其进程环境
- 进程环境与进程控制
- 进程学习2--进程环境
- Unix环境编程-进程环境
- UNIX进程环境小结
- APUE进程环境
- 【C++ 学习笔记小程序04】 char和小整数
- mac os X 与 iOS备忘录
- Redis基础之有序集合
- HDU_4099_Revenge of Fibonacci_Trie树,高精度
- Oracle零基础学习第三次课----表、字段类型、约束
- 进程环境
- java类的初始化顺序
- uva--993Product of digits
- Java-前奏
- Linux目录文件
- 隐马尔可夫模型(HMM)攻略
- javaweb学习总结(八)——HttpServletResponse对象(二)
- Java andorid layout
- WPF lisview 绑定数据