本文将使用Linux操作系统探讨进程的优先级和环境变量。
进程优先级
cpu中的资源是有限的,如何合理分配cpu中的资源给进程,也是操作系统需要考虑的事情。那么既然要分配,资源分配肯定就要有先后顺序,而这就是指进程的优先级。
优先级高的进程有优先执行权利,能优先分配到资源。配置进程优先权对多任务环境的linux很有用,可以改善系统性能。
查看进程优先级
我们还是使用之前的ps命令查看进程的属性。
bash
ps -l

- UID:执行者的身份
- PID:进程序列号,唯一标识符
- PPID:父进程的序列号,唯一标识符
- PRI:进程可被执行的优先级,值越小越先被执行
- NI:表示进程的nice值
PRI
PRI就是进程的最终优先级。PRI的值越小,被CPU执行的先后顺序越靠前。优先级高的进程会更频繁地获得CPU时间片,或者时间片更长。
PRI传承Priority,表示内核当前的调度优先级,它表示进程最后呈现出的优先级。
那么,我们能不能对PRI(优先级)进行修改呢?
PRI = 100 + NI + 动态调整值
而这个NI,即nice值,就是进程优先级的修正数据。
NI
通过更改进程的nice值,就能调整该程序的执行优先级。不过,我们并不能随意更改进程优先级,比如一直让我们写的某个代码程序最优先执行;因此,nice值被限制了一个范围。
nice : [-20 , 19]
这就是我们能调整的优先级范围。
如何更改?
那么我们怎样去修改nice值呢?
top
top命令是用于调整优先级的方法。不过要想修改,我们需要使用root账号。top一共有三步:
输入r ==> 输入进程PID ==> 输入nice值;其中,nice:[-20 , 19] !
我们创建一个test文件用于测试:
cpp
#include <stdio.h>
int main()
{
while(1)
{
printf("this is a test...\n");
sleep(1);
}
return 0;
}
之后用gcc编译一下,得到a.out文件:
bash
gcc test.c

这里我们运行之后在新窗口先查看进程的属性:
bash
ps -la

看到进程的pid为13788。

按下r键后输入PID,之后敲回车再输入NI值:

这样就可以看到优先级被修改了。

尽管我们可以对进程的优先级做修改,但是一般我们是不会去主动修改一个进程的优先级的。我们知道可以并如何去修改就可以了。
命令行参数
经过对进程的学习,我们已经掌握了进程的概念,学习了进程的属性,了解了进程状态。在这之后,我们还需要学习一个新的概念------环境变量。不过,在正式开始介绍环境变量之前,我们先来学习命令行参数。
什么是命令行参数?
以c语言为例,我们知道main函数是程序的入口。那么,main函数是否可以带参数呢?
答案是肯定的。main函数是带参的。具体如下:
cpp
int main(int argc,char *argv[])
{
return 0;
}
上面的这两个参数就是命令行参数。其中argc表示argv数组中元素的个数;argv是一个指针数组,用于存放指向字符类型的指针。那么这个数组到底有多少个元素,里面存放的又是什么内容呢?
我们可以遍历数组将元素打印出来:
cpp
int main(int argc,char *argv[])
{
for(int i=0;i<argc;i++)
{
printf("argv[%d]: %s\n",i,argv[i]);
}
return 0;
}
文件结构为:

运行一下查看结果:

可以看到数组只有一个元素。不过如果我们像下面一样输入:

我们发现随着输入的不同数组的元素也会改变。
我们输入的命令在bash看来也就是一些字符串。他会将我们输入的字符串根据空格打散;例如./mycmd -a 就被打散成两个字符串,再初始化argc的值为2,再通过指针指向这两个字符串存入数组中。
为什么要这么做?
通过上面的代码,我们不理解为什么要进行这样的操作。我们看一段代码就明白了:
cpp
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc,char *argv[])
{
if(argc != 2)
{
//说明只能后面带一个选项
printf("Usage:%s -[a|b|c|d]\n",argv[0]);
return 0;
}
//判断选项
if(strcmp(argv[1],"-a") == 0)
{
printf("功能1\n");
}
if(strcmp(argv[1],"-b") == 0)
{
printf("功能2\n");
}
if(strcmp(argv[1],"-c") == 0)
{
printf("功能3\n");
}
if(strcmp(argv[1],"-d") == 0)
{
printf("功能4\n");
}
return 0;
}
运行如下:

这不就是我们用的命令的选项吗??所以,命令行参数可以为指令、工具、软件等提供命令行选项。
环境变量
平时我们根据网络上的教程安装某些软件时会有一个配置环境变量的操作;那么在windows中的环境变量和Linux中指的就是同一个东西。我们打开设置可以找到:

可以看到有用户变量和系统变量,这些都是环境变量,并且环境变量有其名字和对应的值。
在上面命令行参数的例子中我们说到main函数也可以带参数。那么除了我们介绍的两个参数,实际上main函数有三个参数:
cpp
int main(int argc,char *argv[],char *env[])
{
return 0;
}
env的结构和argv的结构是一模一样的。所以我们用同样的方法遍历env数组查看它的元素:
cpp
#include <stdio.h>
int main(int argc,char *argv[],char *env[])
{
int i=0;
for(;env[i];i++)
{
printf("env[%d] -> %s\n";i,env[i]);
}
return 0;
}
运行后查看结果:

这样就能打印出当前所有的环境变量。
我们所运行的进程都是子进程;bash本身在启动的时候,会从操作系统的配置文件中读取环境变量信息;++子进程会继承父进程交给的所有环境变量++。这就是全局属性。
查找环境变量
我们也可以直接在命令行中对环境变量进行查找:
bash
env

环境变量具有全局属性,我们用命令查找到的环境变量与上面代码执行的进程的环境变量是一样的。
上面的方法是查看所有的环境变量,那么有没有方法可以查看一个指定的环境变量呢?
查看一个指定的环境变量,我们可以使用echo来打印出其路径。比如我们想要查找PYTH环境变量,就需要如下的命令:
bash
echo $PATH

打印出的结果是系统遍历文件夹对PATH进行查找,文件夹之间用:进行分隔。
环境变量的添加和删除
环境变量的添加需要该环境变量的名称和值。如下通过export导入即可添加:
bash
export MY_VALUE=123456
之后我们查找一下,发现成功添加:
bash
env | grep MY_VALUE

而删除一个环境变量的操作如下:
bash
unset MY_VALUE
使用unset即可取消(删除)。
环境变量是系统提供的一组 name = value 形式的变量。不同的环境变量有不同的用途,通常具有全局属性。