在生活中,无论什么时,又会有轻重缓急,人们会据此安排事情的执行逻辑。计算机也是一样,计算机通过优先级的概念合理安排进程运行。环境变量也是学习操作系统的一个重要概念,是操作系统能够正常运行的关键。本文将着重介绍Linux下进程优先级与环境变量的相关内容。
目录
进程优先级
一、基本概念
二、查看系统进程
三、更改进程优先级
四、其它相关概念
环境变量
一、基本概念
二、环境变量的相关指令
三、通过代码获取环境变量
(1)命令行参数
(2)通过第三方变量environ获取
(3)通过系统调用获取环境变量
四、环境变量的全局属性
为什么会存在进程优先级这样的概念呢?原因是资源太少,需要进行合理的配置。引入进程优先级本质是分配资源的一种方式。
CPU资源分配的先后顺序,就是指进程的优先权。优先权高的进程有优先执行权力。配置进程优先权对多任务环境的Linux很有用,可以改善系统性能。还可以把进程运行到指定的cpu上,这样一来,把不重要的进程安排到某个CPU,可以大大改善系统整体性能。
使用ps -al指令可以查看进程的优先级,效果如下:
其中有些内容是我们熟知的,如PID以及PPID。而与进程优先级相关的内容是PRI和NI。
PRI:进程优先级,即程序被CPU执行的先后顺序,值越小进程的优先级越高。
NI:即nice值,表示进程优先级的的修正值。所谓修正值就体现在新的优先级 = 旧的优先级 + NI。nice值为负,进程优先级减小,进程优先级变高;反之nice值为正,进程优先级增大,进程优先级变低。
注:nice的取值共有-20至19一共40个级别
更改进程优先级可以使用top指令,使用方法:进入top后按r,输入进程PID,输入nice值。通过更改nice来更改进程的优先级。
进程myproc的初始状态如下:
更改完成,使用ps -al查看进程新的优先级:
此时nice值变为了10,而优先级变成了90(80 + 10)。
如果我们继续重复上面的操作,会将进程优先级变为100吗?
最终的结果是:进程myproc的优先级仍然是90,nice值还是10。由此可能,nice是以优先级80为基准进行修正的。若想将优先级设置为100,自然要设置nice值为20。
因为nice只能取-20至19,进程的优先级也就只能取得60-99。为何要将nice至设定在一个相对较小的范围呢?因为优先级无论怎么设置,也只能是一种相对优先的概念,不能出现绝对的优先,否则就会出现很严重的进程饥饿问题。
竞争性:系统进程数目众多,而CPU资源只有少量,甚至只有1个,所以进程之间是具有竞争属性的。为了高效完成任务,更加合理地竞争相关资源,便具有了优先级。
独立性:多进程运行,需要独享各种资源,多进程运行期间互不干扰。
并行:多个进程在多个CPU下分别同时进行运行。
并发:多个进程在一个CPU下采用进程切换的方式,在一段时间内,让多个进程都得以推进,称之为并发。
众所周知,在Linux环境下,命令、程序、工具……本质都是一个个可执行文件。我们在运行自己的程序时,往往会加上它所在的路径,如./myproc。但我们在执行系统命令(如ls、pwd)时为何不用带路径呢?这都是因为系统中存在环境变量。环境变量就是指在操作系统中用来指定操作系统运行环境的一些参数。
常见的环境变量如下:
PATH:指定命令的搜索路径。
HOME:指定用户的主工作目录(即用户登入到Linux系统中的默认目录)。
SHELL:当前Shell。
在查看环境变量时,可以使用echo $环境变量名,使用效果如下:
当我们使用系统命令时,系统会自动在上述路径查找。由此可见,如果我们将自己程序的路径也加入环境变量中,自然在调用时也不需要指定路径了。
语义上定义变量的本质是在内存中开辟空间。而环境变量的本质是在内存/磁盘文件中开辟空间,保存系统相关的数据。
系统上还存在一种变量,与本次登入有关,只在本次登入有效——本地变量。
定义一个本地变量:
我们也可以使用指令env显示所有环境变量。首先使用env查找刚刚定义的本地变量:
自然是数目也查询不到,因为temp并不是环境变量。此时再引入一个指令export,用于将本地变量变为环境变量。使用改指令将temp变为环境变量再进行查找:
在编写C语言代码时,我们可以为main函数加入参数:
int main(int argc, char* argv[], char* env[])
{
return 0;
}
那么这些参数都有什么用处呢?我们知道系统指令往往有很多选项,用来完成同一命令的不同子功能。而完成这一效果的底层原理就是命令行参数。
argv是一个指针数组,每个指针都指向一个选项,而argc表示argv数组中元素的个数。
测试代码:
#include
int main(int argc, char* argv[], char* env[])
{
for(int i = 0; i < argc; ++i)
{
std::cout << i << ':' << argv[i] << std::endl;
}
return 0;
}
运行结果:
弄清了argc和argv的作用,只剩下了参数env。从它的名字就可以猜出,env数组所存储的自然就是环境变量了。
测试代码:
#include
int main(int argc, char* argv[], char* env[])
{
for(int i = 0; env[i]; ++i)
{
std::cout << i << ':' << env[i] << std::endl;
}
return 0;
}
运行结果:
由此也可以推导出命令行参数的组织形式:
environ是一个指向环境变量数组的指针,由此可以通过访问这个第三方变量获取环境变量。
测试代码:
#include
int main(int argc, char* argv[], char* env[])
{
extern char** environ;
for(int i = 0; environ[i]; ++i)
{
std::cout << i << ':' << environ[i] << std::endl;
}
return 0;
}
运行结果:
getenv()获取环境变量。
测试代码:
#include
#include
int main()
{
std::cout << getenv("PATH") << std::endl;
return 0;
}
运行结果:
我们知道命令行上启动的进程,其父进程都是bash。也正是因此,环境变量可以被这些子进程一直继承下去。
为了验证这一点,我们先创建一个自己的环境变量MYENV。
测试代码:
#include
#include
int main()
{
std::cout << getenv("MYENV") << std::endl;
return 0;
}
运行结果: