进程优先级、环境变量、虚拟地址空间
一:进程优先级
cpu分配资源的先后顺序即为进程的优先级;
优先级高的进程有优先执行权利。配置进程优先级对多任务环境的linux很有用,可以改善系统性能;
可以把进程运行到指定的cpu上,把不重要的进程安排到某个CPU,只能这个进程使用,cpu不用切换,CPU核心可以独立运行,即有独立的寄存器。
进程优先级:
交互式进程:优先级较高;
批处理进程:优先级较低(运行在操作系统后台,循环干一件事);
查看进程优先级:ps - l
UID:代表执行者的身份;
PID:代表进程的代号;
PPID:代表进程是由哪个进程衍生而来,即父进程代号;
PRI:代表这个进程可被执行的优先级,其值越小越早被执行;
NI:即nice值,调整进程优先级的参数。
注:PRI越小越早执行,用nice修改PRI,PRI(new)=PRI(old)+nice;nice 值的取值范围是-20-19,一共40个级别;当nice值越小,程序优先级越小,就越早被执行;因此可以用nice调整进程优先级。
nice
nice是启动进程前调整优先级
renice
renice是程序运行过程中调整优先级,已经提前./tmp
注:是直接将nice值修改为20,但由于nice取值范围是-20-19,如果超范围将用最大值代替即19。
4个性质
竞争性:由于系统进程数量较多,而cpu资源有限,那么进程间就存在竞争关系;优先级高的进程cpu优先处理;
独立性:多进程运行,需要独享各种资源,多进程运行期间互不干扰;
并行性:多个进程在多个cpu下同时进行运行;
并发性:多个进程在一个cpu采用cpu计时技术即进程切换方式,在一段时间内,多个进程依次被处理;
二:环境变量
指在操作系统具有特殊功能的参数变量,环境变量具有全局性。当我们在编写c/c++代码时,在链接时,尽管不知道链接的动静态库在哪儿,但依然可以链接成功,生成可执行程序,是因为有相关环境变量会帮助编译器查找。
常见环境变量:PATH(指定命令的搜索路径);
HOME(用户登录到linux系统时默认的目录);
查看环境变量
echo是打印字符串,用$使之成为一个变量。
用代码查看环境变量
1.利用main的第三个参数
1 #include<stdio.h>
2
3 int main(int argc,char*argv[],char *env[])
4 {
5 int i=0;
6 for(i=0;env[i];i++)
7 {
8 printf("%d :%s\n",i,env[i] );
9 }
10 return 0;
11 }
2.利用全局变量environ
全局变量environ指向环境变量表,environ没有包含在任何头文件中,使用时需要用extern声明。
1 #include<stdio.h>
2 //environ是环境变量
3 int main()
4 {
5 extern char **environ;
6 int i=0;
7 while(environ[i])
8 {
9 printf("%d %s\n",i,environ[i]);
10 i++;
11 }
12 return 0;
13 }
3.通过系统调用获取或者设置环境变量
getenv();
1 #include<stdio.h>
2 #include<stdlib.h>
3 int main()
4 {
5 printf("PATH:%s\n",getenv("PATH"));
6 printf("HOME:%s\n",getenv("HOME"));
7 return 0;
8 }
export和unset
1 #include<stdio.h>
2 #include<stdlib.h>
3 int main()
4 {
5 printf("PATH:%s\n",getenv("PATH"));
6 printf("HOME:%s\n",getenv("HOME"));
7 printf("MYENVAL:%s\n",getenv("MYENVAL"));
8 printf("VAL:%s\n",getenv("VAL"));
9 return 0;
10 }
因为环境变量具有全局性,由图可知MYENVAL不是一个环境变量,只是一个本地变量。但是用export可以将MYENVAL设置为一个环境变量:
同样export可以设置一个新环境变量:
可以用unset清除环境变量:
可以用env和set查看环境变量:
env:
set:
注:没有列全,set查看的环境变量比env所查看的多。
三:程序地址空间(虚拟地址空间)
1 #include<stdio.h>
2 #include<unistd.h>
3 #include<stdlib.h>
4
5 int main()
6 {
7 int val=100;
8 pid_t pid=0;
9 pid=fork();
10 if(pid<0)
11 {
12 perror("fork");
13 return 0;
14 }
15 else if(pid==0)
16 {
17 // val=200;
18 printf("child[%d]:%d:%p\n",getpid(),val,&val);
19 }
20 else
21 {
22 printf("parent[%d]:%d:%p\n",getpid(),val,&val);
23 }
24 sleep(1);
25 return 0;
26 }
输出的变量值和地址一样,可以理解为子进程是以父进程为模板的复制;但是在将子进程里的//val=200;去掉注释,又会变成什么样呢?
地址相同,但是变量值不同,可以得出以下结论:
变量内容不同,说明父子进程输出的变量不是一个变量;但地址相同,则说明该地址不是物理地址,在linux下,该地址称为虚拟地址,通常在c/c++中&变量得到的地址都为虚拟地址,而物理地址被OS同一管理,用户看不见。
所以上面一张图实质上是虚拟地址,那怎么从虚拟地址转换为真正意义上的物理内存地址呢?
早期内存管理机制
分段
页表映射
上一篇: 滑动验证码实践