Linux的进程认识下
1:环境变量
1:基础概念
环境变量(environment variables)⼀般是指在操作系统中⽤来指定操作系统运⾏环境的⼀些参数
如:我们在编写C/C++代码的时候,在链接的时候,从来不知道我们的所链接的动态静态库在哪
⾥,但是照样可以链接成功,⽣成可执⾏程序,原因就是有相关环境变量帮助编译器进⾏查找。
环境变量通常具有某些特殊⽤途,还有在系统当中通常具有全局特性
2:常见的环境变量
PATH : 指定命令的搜索路径
HOME : 指定⽤⼾的主⼯作⽬录(即⽤⼾登陆到Linux系统中时,默认的⽬录)
SHELL : 当前Shell,它的值通常是/bin/bash。
3:查看环境变量的方法
echo $NAME //NAME:你的环境变量名称
测试PATH
1:创建hello.c文件
#include <stdio.h>int main()
{printf("hello world!\n");return 0;
}2:对比./hello执行和hello的执行
3:为什么有的指令可以直接执行,不需要带路径,而我们的二进制文件需要带路径才能执行
4:将我们的程序所在的路径加入环境变量PATH中,export PATH=$PATH:HELLO程序所在路径
5:对比测试
测试HOME
1:用root用户和普通用户分别执行echo $HOME对比差异
2:执行cd ~;pwd,对应~和HOME的关系
4:和环境变量有关的命令

5:环境变量的组织方式

每一个程序都会收到一张环境表,环境表是一个字符指针数组,每一个指针指向一个以'\0'结尾的环境字符串
6:通过系统调用获取和设置环境变量
putenv()
getenv()
7:环境变量的全局属性
环境变量通常具有全局属性,可以被子进程继承下去
#include <stdio.h>
#include <stdlib.h>
int main()
{
char *env = getenv("MYENV");
if(env){
printf("%s\n", env);
}
return 0;
}2:程序地址空间
在C语言的基础上,我们在Linux的环境下加深一下对应空间分布图的理解

验证一下
#include <stdio.h>
#include <stdlib.h>
extern char **environ; // 环境变量指针,由系统提供// 1. 初始化数据区:已初始化的全局变量
int init_global = 10;
// 2. 未初始化数据区(BSS段):未初始化的全局变量
int uninit_global;// 栈区测试函数
void stack_test() {int stack_var = 20; // 栈区局部变量printf("栈区-函数内局部变量地址: %p\n", &stack_var);
}int main(int argc, char *argv[]) {// 3. 正文代码区:函数指令的地址printf("正文代码区-main函数地址: %p\n", main);// 4. 初始化数据区:已初始化全局变量printf("初始化数据区-已初始化全局变量地址: %p\n", &init_global);// 5. 未初始化数据区(BSS段):未初始化全局变量printf("未初始化数据区-未初始化全局变量地址: %p\n", &uninit_global);// 6. 堆区:动态分配内存void *heap_ptr = malloc(100);printf("堆区-malloc分配内存地址: %p\n", heap_ptr);free(heap_ptr); // 释放堆内存(避免内存泄漏)// 7. 栈区:main函数内局部变量int main_stack_var = 30;printf("栈区-main函数内局部变量地址: %p\n", &main_stack_var);stack_test(); // 调用函数,查看函数内栈变量地址// 8. 命令行参数区:argv指针及参数地址printf("命令行参数区-argv指针地址: %p\n", argv);for (int i = 0; i < argc; i++) {printf(" argv[%d]地址: %p, 内容: %s\n", i, argv[i], argv[i]);}// 9. 环境变量区:environ指针及环境变量地址printf("环境变量区-environ指针地址: %p\n", environ);for (char **env = environ; *env != NULL; env++) {printf(" 环境变量地址: %p, 内容: %s\n", *env, *env);break; // 只打印一个环境变量,避免输出过多}// 10. 共享区:动态链接库函数地址(如printf)printf("共享区-printf函数地址: %p\n", printf);return 0;
}结果

3:进程地址空间
分页和虚拟地址空间

上⾯的图就⾜矣说明问题,同⼀个变量,地址相同,其实是虚拟地址相同,内容不同其实是被映
射到了不同的物理地址!
