文章目录
🌲进程优先级
🌴优先级和权限的区别
以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);
}
}