目录
2.9 通过系统调用获取或设置环境变量getenv和putenv
1、进程优先级
1.1 基本概念
- cpu资源分配的先后顺序,就是指进程的优先权(priority)。
- 优先权高的进程有优先执行权利。
- 配置进程优先权对多任务环境的linux很有用,可以改善系统性能。 还可以把进程运行到指定的CPU上,这样一来,把不重要的进程安排到某个CPU,可以大大改善系统整体性能。
1.2 查看系统进程
在linux或者unix系统中,用ps –l命令则会类似输出以下几个内容:
我们很容易注意到其中的几个重要信息,有下:
UID : 代表执行者的身份
PID : 代表这个进程的代号
PPID :代表这个进程是由哪个进程发展衍生而来的,亦即父进程的代号
PRI :代表这个进程可被执行的优先级,其值越小越早被执行
NI :代表这个进程的nice值
1.3 PRI and NI
- PRI也还是比较好理解的,即进程的优先级,或者通俗点说就是程序被CPU执行的先后顺序,此值越小进程的优先级别越高
- 那NI呢?就是我们所要说的nice值了,其表示进程可被执行的优先级的修正数值
- PRI值越小越快被执行,那么加入nice值后,将会使得PRI变为:PRI(new)=PRI(old)+nice
- 这样,当nice值为负值的时候,那么该程序将会优先级值将变小,即其优先级会变高,则其越快被执行
- 所以,调整进程优先级,在Linux下,就是调整进程nice值
- nice其取值范围是-20至19,一共40个级别。
1.4 PRI vs NI
- 需要强调一点的是,进程的nice值不是进程的优先级,他们不是一个概念,但是进程nice值会影响到进程的优先级变化。
- 可以理解nice值是进程优先级的修正修正数据
1.5 查看进程优先级的命令
用top命令更改已存在进程的nice:
top 进入top后
按“r”–>输入进程PID–>输入nice值(设置值不能太大也不能太小)
每次设置优先级,都是基于进程最开始的默认优先级进行设置的
1.6 其他概念
- 竞争性: 系统进程数目众多,而CPU资源只有少量,甚至1个,所以进程之间是具有竞争属性的。为了高效完成任务,更合理竞争相关资源,便具有了优先级
- 独立性: 多进程运行,需要独享各种资源,多进程运行期间互不干扰
- 并行: 多个进程在多个CPU下分别,同时进行运行,这称之为并行
- 并发: 多个进程在一个CPU下采用进程切换的方式,在一段时间之内,让多个进程都得以推进,称之为并发
cpu内的寄存器只有一份,但是上下文可以有多份,分别对应不同的进程!(上下文保护)
2、环境变量
2.1 基本概念
- 环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数
- 如:我们在编写C/C++代码的时候,在链接的时候,从来不知道我们的所链接的动态静态库在哪里,但是照样可以链接成功,生成可执行程序,原因就是有相关环境变量帮助编译器进行查找。
- 环境变量通常具有某些特殊用途,还有在系统当中通常具有全局特性
2.2 常见环境变量
PATH : 指定命令的搜索路径
HOME : 指定用户的主工作目录(即用户登陆到Linux系统中时,默认的目录)
SHELL : 当前Shell,它的值通常是/bin/bash。
2.3 查看环境变量方法
echo $NAME //NAME:你的环境变量名称
运行系统程序会在上图每个环境变量路径下,寻找是否有此程序,有便可直接运行
2.4 测试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. 对比测试
6. 还有什么方法可以不用带路径,直接就可以运行呢?
将其路径设置至环境变量中,便可直接在认何地方运行,不用带./
PATH就是指定其搜索指定路径
2.5 测试HOME
1. 用root和普通用户,分别执行 echo $HOME ,对比差异 . 执行 cd ~; pwd ,对应 ~ 和 HOME 的关系
其中,普通用户 cd ~会进入当前用户的家目录
root,会进入root家目录
2.6 和环境变量相关的命令
1. echo: 显示某个环境变量值
2. export: 设置一个新的环境变量
3. env: 显示所有环境变量
4. unset: 清除环境变量
5. set: 显示本地定义的shell变量和环境变量
2.7 环境变量的组织方式
每个程序都会收到一张环境表,环境表是一个字符指针数组,每个指针指向一个以’\0’结尾的环境字符串
char *env【】其每一个参数都是char* 的参数,就是环境表
2.8 通过代码获取环境变量(main函数的第三个参数)
命令行第三个参数
#include <stdio.h> int main(int argc, char *argv[], char *env[]) { int i = 0; for(; env[i]; i++){ printf("%s\n", env[i]); } return 0; }
通过第三方变量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; }
libc中定义的全局变量environ指向环境变量表,environ没有包含在任何头文件中,所以在使用时要用extern声明。
2.9 通过系统调用获取或设置环境变量getenv和putenv
getenv
getenv()函数在环境列表中搜索环境变量名,并返回一个指向相应值字符串的指针。
#include <stdio.h> #include <stdlib.h> int main() { printf("%s\n", getenv("PATH")); return 0; }
putenv
1、putenv()函数的作用是添加或修改环境变量的值。
2、参数字符串的形式是name=value。如果环境中不存在name,则将string添加到环境中,如果name确实存在,则环境中name的值将更改为value。
3、字符串所指向的字符串成为环境的一部分,因此改变字符串也改变了环境。
4、返回值putenv()函数在成功时返回零,如果发生错误则返回非零。
5、如果发生错误,则设置errno来指示原因。错误没有足够的空间分配新环境。
2.10 环境变量通常具有全局属性
环境变量通常具有全局属性,可以被子进程继承下去
#include <stdio.h> #include <stdlib.h> int main() { printf("%s\n", getenv("testFor_11")); return 0; }
1、子进程继承了父进程的环境变量
2、默认所有的环境变量都会被子进程继承
通过 export testFor_11=你好, 设置环境变量,在通过系统调用getenv获取可得出设置其信息值,因此可得出以上结论。
2.11 main函数的另外两个参数
int argc: 记录其运行进程及后续输入字符串个数,同时包含进程./本身
char *argv[]:记录每个字符串内容
如图其中 argc 为 3,对应的argv分别是 "./argctest","-a","-b"
因此,如下代码:
#include<stdio.h> #include<string.h> int main(int argc,char *argv[]){ if(argc < 2){ printf("usage:%s! Lack of options\n",argv[0]); } if(argc == 3 && strcmp("-a",argv[1]) == 0 && strcmp("-b",argv[2]) == 0){ printf("这是选项-a-b\n"); return 0; } if(strcmp("-a", argv[1]) == 0){ printf("这是选项-a\n"); }else if(strcmp("-b",argv[1]) == 0){ printf("这是选项-b\n"); }else{ printf("无此选项\n"); } return 0; }
因此,可知Linux命令行程序,及其选项,正是通过设置其全局属性的环境变量,并传递相关int argc与char *argv[]两个命令行参数进行判断执行