文章目录
进程优先级
优先级是什么?
为什么要有优先级?
Linux 里进程优先级由谁决定?
更改优先级
设定 nice 的值
Linux 标识用户
进程补充
环境变量
什么是环境变量?
环境变量种类
常见的环境变量
查看环境变量
直接运行可执行程序的办法(不加./)
环境变量具有全局性
获取环境变量
补充命令
命令行参数
示例: 计算器功能
进程优先级
优先级和权限的区别
以 CPU 资源为例, 优先级是一定能获得 CPU 资源, 只是时间的长短
权限则不同, 权限不够就不能获得资源
优先级是什么?
优先级本质就是获得资源的先后顺序
为什么要有优先级?
CPU 的资源有限, 所以进程需要根据优先级排队
Linux 里进程优先级由谁决定?
两个参数: PRI 和 NI
PRI 可看作 priority 的简写, NI 指的是 nice 值(新概念)
更改 nice 值可以改变优先级
PRI 越小, 优先级越高, 反之越低(一般创建的进程 PRI 默认是 80)
NI 的取值范围是 - 20 到 19(把 NI 设为 100 等同于设为 19 把 NI 设为 - 100 等同于设为 - 20),NI 的值是可控状态
ps -al 看到 PRI 和 NI
更改优先级
优先级看 PRI 的值, PRI 的值决定排名, NI 的值可以更改 PRI, 进而影响优先级
PRI(新)=PRI(旧)+NI
注: 这个 PRI(旧)一般指 80(PRI 的值默认一般是八十)
设 NI 的值 | PRI(同一个进程) |
---|---|
0 | 80 |
10 | 90 |
13 | 93(不会变成 103) |
连续设定 NI 的值不会累加, 80 是一个基准, 这是为了防止一个进程的优先级过高或者过低, 进而保证 CPU 资源的公平分配. 在设计上也比较简单
如果可以累加, 用户操作时可能造成一个进程的优先级相当高, 而别的进程优先级很低, 导致资源的不公平分配, 而 CPU 调度器的原则就是公平, 所以过高和过低是不被允许的, 正因为如此, NI 的值不会被累加, 每次调整的基准都是 80
设定 nice 的值
top 命令
top -> r 选项 ->输入 PID -> 输入设定的 renice (按 q 退出 top)
注: 改了两次 NI, 但是第二次改变的结果仍然是以 80 为基准得到的
Linux 标识用户
Linux 标识用户是根据 UID 来的, 而不是根据用户名
ll-n 可以看到 uid
比如 qq 里标识我们的不是 qq 名, 而是我们的 qq 号
随笔记录计算机善于处理数字数据
进程补充
独立性: 每个进程相互独立
fork 创建子进程时, 共享代码, 私有数据, 就是为了维护进程的独立性
竞争性: 资源是有限的, 自然就有了竞争, 为了高效的完成任务, 合理竞争, 也就产生了优先级, 优先级高的先分配到 CPU 资源
环境变量
什么是环境变量?
环境变量 (environment variables) 一般是指在操作系统中用来指定操作系统运行环境的一些参数, 如: 临时文件夹位置和系统文件夹位置等.- 百度百科
例 1, 如果在 Windows 下配过 Java 的环境那肯定见过下面这张图
例 2:C 文件的编译与链接, 链接时就需要库的参与, 动态库静态库之类的, 那编译器是怎么找到动态库或静态库的? 就是借助了环境变量
例 3:Linux 下有一个名为 test 的可执行文件, ./test 运行程序, 其实 "./test" 也可以看作一条指令, 我们为什么要在可执行程序前加 ./ ?(我们不用在 ls,ll,pwd 等等前面加 ==./== 啊)
原因: "./" 可以帮助 Linux 找到当前的可执行文件的路径, Linux 在执行可执行文件时默认在 PATH(环境变量)里面去找文件路径, 找到的第一条将被执行
因为 ls,pwd 这些命令本就在环境变量设置的目录下, 所以不用加 "./" Linux 系统也能找到 ls,pwd 然后执行
换句话说 , 如果我们在环境变量中移除了 ls,pwd 这些命令所在的目录, 那我们就不能直接用 ls,pwd 这些命令, 因为 Linux 找不到这些命令就会报错:-bash: xxx: command not found, 此外, 路径名中存在 './' , 则不搜索 $PATH(一种环境变量)
Windows 默认带了查找路径 所以执行可执行文件不用加./
环境变量种类
本地变量和环境变量
本地变量只能在 shell 内访问, 不能被子进程继承
常见的环境变量
PATH: 指定命令的搜索路径
PATH: 辅助系统进行命令查找
PATH 下的路径以:(冒号)做分隔符
HOME: 用户的工作目录
用户通过登录 进入系统时所在的目录
SHELL: 当前 Shell
HISTSIZE: 保存历史命令的数目
history 命令可以看到自己敲过的指令, 一般是默认保存最近的 3000 条
HISTSIZE 的值默认就是 3000
查看环境变量
echo $ 变量名
如
echo $PATH
echo $HOME
echo $SHELL
echo $HISTSIZE
env
可以看到所有的环境变量
set
显示或设置 shell 特性及 shell 变量
直接运行可执行程序的办法(不加./)
文件拷贝至 PATH 下
注: 文件名别取 test, 不然会失败(我一开始文件名取了 test, 在 PATH 下的目录里面也能找到 test, 但是不能直接运行)
把当前目录添加到 PATH 下
PATH=$PATH: 路径
$PATH 代表原路径
关掉重启后环境变量又会恢复默认
记录 PATH: 怕玩崩了
/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/ck/.local/bin:/home/ck/bin
环境变量具有全局性
全局属性: 可以被子进程继承
获取环境变量
通过全局属性 我们可以通过子进程获取父进程的环境变量(因为子进程继承了父进程的环境变量, 所以父子的环境变量一样)
通过 C 语言 getenv(变量名) 函数
- test.c
- #include<stdio.h>
- #include<stdlib.h>
- int main()
- {
- printf("PATH:%s\n",getenv("PATH")); // 得到当前的 PATH
- printf("HOME:%s\n",getenv("HOME"));
- printf("SHELL:%s\n",getenv("SHELL"));
- return 0;
- }
运行:
这个 C 程序加载到内存就是个进程, 它的父进程就是 bash(前面的 Linux 笔记有讲过, 可以翻一下)
在命令行运行的大部分的指令, 它的父进程都是 bash, 也即 bash 创建子进程, 子进程执行你的指令
前面提过本地变量只能在 shell 内访问, 不能被子进程继承
假定本地变量 MY_VAL=15
C 代码: getenv("MY_VAL"); 这种写法就是错误的, 因为在子进程无法访问到本地变量
如何访问在子进程里访问本地变量?
加 export
利用 set 测试
利用 getenv 函数测试
随笔小结: env 只能看到环境变量 而 set 都可以看 可以利用这点来判断是否是环境变量
echo set env 等为内建命令, 是 shell 程序内部函数 父进程不是 bash
补充命令
unset: 取消环境变量
如 unset MY_VAL
命令行参数
- test.c
- #include<stdio.h>
- #include<stdlib.h>
- int main(int argc,char* argv[])
- {
- for(int i=0;i<argc;i++)
- //i<argc 可以写成 argv[i], 因为 argv 数组最后一个元素为 NULL
- {
- printf("argv[%d]:%s\n",i,argv[i]);
- }
- return 0;
- }
上面的 agrc,argv 就是命令行参数
注: 运行时得用 C99 标准 即 gcc -o test test.c -std=c99
运行:
此外 main 函数还有第三个参数 env , 可以通过 env 来获取当前环境
- #include<stdio.h>
- #include<stdlib.h>
- int main(int argc,char* argv[],char* env[])
- {
- for(int i=0;env[i];i++)
- //env 里放的就是 env 命令获取的内容
- {
- printf("env[%d]:%s\n",i,env[i]);
- }
- return 0;
- }
getenv()这个函数就是对 env 数组进行了信息筛选
上面程序等价于
- #include<stdio.h>
- #include<stdlib.h>
- int main(int argc,char* argv[])
- {
- extern char** environ; // 二级指针
- for(int i=0;environ[i];i++)//env 里放的就是 env 命令获取的内容
- {
- printf("env[%d]:%s\n",i,environ[i]);
- }
- return 0;
- }
environ 是一个全局的外部变量 , 可以通过 extern 声明
这个变量在 unistd.h 中 所以也可以包含头文件使用
为什么要有命令行参数?
让一个程序可以实现不同功能
示例: 计算器功能
计算器源码:
- #include<stdio.h>
- #include<stdlib.h>
- #include<string.h>
- int main(int argc,char* argv[] )
- {
- int num1=atoi(argv[2]);
- int num2=atoi(argv[3]);
- if(argc!=4)
- {
- printf("Usage:./cal -a(s) num num\n");
- }
- if(strcmp(argv[1],"-a")&&strcmp(argv[1],"-s"))
- {
- printf("Usage:./cal -a(s) num num\n");
- }
- else if(!strcmp(argv[1],"-a"))
- {
- printf("%d %d=%d\n",num1,num2,num1+num2);
- }
- else
- {
- printf("%d-%d=%d\n",num1,num2,num1-num2);
- }
- }
来源: https://blog.csdn.net/m0_53005929/article/details/122516586