环境变量
基本概念
- 环境变量一般是指在操作系统中用来指定操作系统运行环境的一些参数
- 如:我们在编写代码的时候,在链接的时候,从来不知道我们所链接的动静态库在哪,但是照样可以链接成功,生成可执行程序,原因是有相关变量帮助编译器查找
- 环境变量具有全局性
常见的环境变量
PATH
:指定命令的搜索路径HOME
:指定用户的主工作目录(即用户登录到Linux系统
中时,默认的目录)
查看环境变量的方法
echo $NAME
//NAME:要查找的环境变量名
获取环境变量的方法
env #显示所有的环境变量
echo $XXX #显示某个环境变量值
export MYENV=112233 #导环境变量
unset MYENV #取消环境变量
环境变量的组织方式
每个程序都会收到一张环境变量表,环境表是一个字符指针数组,每个指针指向一个以'\0'
结尾的环境字符串
通过代码获取环境变量
- 命令行第三个参数
#include <stdio.h>
#include <stdlib.h>
int main(int argc,char* argv[],char* env[])
{
int i=0;
for(;env[i];i++)
{
printf("env[%d]:%s\n",i,env[i]);
}
}
- 通过第三方变量environ获取
#include <stdio.h>
int main(int argc, char *argv[])
{
extern char **environ;
int i = 0;
for(; environ[i]; i++){
printf("%s\n", environ[i]);
}
return 0;
}
- 通过系统调用获取或设置环境变量
#include <stdio.h>
#include <stdlib.h>
int main()
{
printf("%s\n",getenv("PATH"));
return 0;
}
常用getenv和putenv函数来访问特定的环境变量
程序地址空间
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int g_val=0;
int main()
{
pid_t id=fork();
if(id<0)
{
perror("fork fail");
return 0;
}
else if(id==0)
{
//child
printf("child[%d]:%d:%p\n",getpid(),g_val,&g_val);
}
else
{
//father
printf("father[%d]:%d:%p\n",getpid(),g_val,&g_val);
}
sleep(1);
return 0;
}
输出
通过上面发现,输出出来的变量值和地址一摸一样
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int g_val=0;
int main()
{
pid_t id=fork();
if(id<0)
{
perror("fork fail");
return 0;
}
else if(id==0)
{
//child
g_val=100;
printf("child[%d]:%d:%p\n",getpid(),g_val,&g_val);
}
else
{
//father
sleep(3);
printf("father[%d]:%d:%p\n",getpid(),g_val,&g_val);
}
sleep(1);
return 0;
}
发现,父子进程,输出地址是一致的,但是变量内容不一样
- 变量内容不一样,所以父子进程输出的变量绝对不是同一个变量
- 但地址一样,说明,该地址绝对不是物理地址
- 在linux地址下,这种地址叫做虚拟地址
- 我们在C/C++语言所看到的地址,全部都是虚拟地址!物理地址,用户看不到
OS必须负责将虚拟地址转化成物理地址
进程地址空间
同一个变量,虚拟地址相同,内容不同其实是被映射到了不同物理地址
虚拟内存管理
描述linux下进程的地址空间的所有的信息的结构体是mm_struct
(内存描述符)。每个进程只有一个mm_struct
结构,在每一个进程的task_struct
结构中,有一个指向该进程的结构
为什么要有虚拟地址空间
- 将地址从无序变成有序
- 地址转化过程中,可以对我们的地址和操作进行合法性判定,进而保护物理内存
- 让内存管理和进程管理进行一定程度的解耦合
char str=“hello world”,str=‘H’;为什么字符常量区写入就会崩溃??
查找页表时,权限拦截了