当前位置 : 主页 > 操作系统 > centos >

[ Linux ] 进程优先级 和 环境变量

来源:互联网 收集:自由互联 发布时间:2022-10-15
在上篇文章我们了解了进程的状态及Linux系统的进程状态,本篇我们主要了解进程优先级及环境变量。 1.进程优先级 说到优先级, 我们首先要清楚什么是优先级,和权限有什么关系呢?

在上篇文章我们了解了进程的状态及Linux系统的进程状态,本篇我们主要了解进程优先级及环境变量。

1.进程优先级

说到优先级,我们首先要清楚什么是优先级,和权限有什么关系呢?

优先级是进程获取资源的先后顺序 ,而权限呢?谈的是能不能,比如:您是一名学生,您要去教室食堂吃饭,此时你是不能去的,因为你没有权限。 而优先级指的是您去学生食堂吃饭,但是可能人多,你需要排队,主要指的是先手顺序,但是一定能吃到饭。

为什么会存在优先级呢?

为什么您在食堂中吃饭需要排队呢?最主要的原因是因为资源不够,系统也是这样的。系统里面永远都是进程占大多数,而资源是少数!因此进程竞争资源是常态!存在竞争一定要确认先后,因此一定会存在优先级。

Linux下优先级的相关概念和操作

  • cpu资源分配的先后顺序,就是指进程的优先权(priority)。
  • 优先权高的进程有优先执行权利。配置进程优先权对多任务环境的linux很有用,可以改善系统性能。
  • 还可以把进程运行到指定的CPU上,这样一来,把不重要的进程安排到某个CPU,可以大大改善系统整体性能。
  • 1.1 Linux下查看进程的优先级

    我们首先模拟一段简单的c语言代码

    #include <stdio.h>
    #include <unistd.h>
    int main()
    {
    while(1)
    {
    printf("hello PRI\n");
    sleep(1);
    }
    return 0;
    }

    我们使用指令查看当前进程的优先级

    ps -la

    [ Linux ] 进程优先级 和 环境变量_优先级

    在Linux进程优先级中由两部分组成:priority(PRI) + nice(NI)

    默认的优先级是80,数字越小表示优先级越高,数字越大表示优先级越低

    1.2 Linux 进程优先级的更改

    要更改进程优先级,需要更改的不是pri,而是NI

    PRI and NI

  • PRI也还是比较好理解的,即进程的优先级,或者通俗点说就是程序被CPU执行的先后顺序,此值越小进程的优先级别越高。
  • 那NI呢?就是我们所要说的nice值了,其表示进程可被执行的优先级的修正数值。
  • 用top命令更改已存在进程的nice:

    进入top后按“r”–>输入进程PID–>输入nice值

    我们使用top指令,再按r,此时系统就会提示让我们输入 PID ,输入我们要renice的PID,因此我们输入要修改的进程的PID

    [ Linux ] 进程优先级 和 环境变量_优先级_02

    此时输入pid后显示让我们输入新的nice的value,这里我们首先输入-100

    [ Linux ] 进程优先级 和 环境变量_环境变量_03

    [ Linux ] 进程优先级 和 环境变量_优先级_04

    这里提示我们没有权限,这是因为一个进程的优先级不能轻易修改,我们想要修改要使用root用户进行修改,我们切到root用户下完成以上操作。

    [ Linux ] 进程优先级 和 环境变量_#include_05


    当我们完成以上操作后我们ctrl + C 退出top后,再次查看进程信息能够发现此时test的pri已经变成了60,而NI值是-20。可是不对呀,我们起始PRI为80,设置的NI为-100,不应该PRI成-20吗?哈哈哈,问出这个问题的同学可以自己想想,我们说进程PRI数字越小进程优先级越高,那你再小能小于0吗,小于0难道让操作系统还要倒贴你。因此操作系统规定NI的取值范围为[-20,19]。比如我们再次使用top,此时renice输入100,验证一下取值范围

    ps -al

    [ Linux ] 进程优先级 和 环境变量_#include_06

    [ Linux ] 进程优先级 和 环境变量_#include_07

    当我们输入100后,我们再次查看进程信息发现,NI的最大值确实为19,而且有一个现象是,PRI变成了99,而不是79。大家会疑惑,第一次我们renice -100时,PRI已经为60了,这里再加19不应该是79吗,为什么是99。这是现象说明了每次PRI值都会恢复为80。最终的PRI都是在80的基础上加上NI值。因此这里会显示99。

    [ Linux ] 进程优先级 和 环境变量_优先级_08


    总结:

  • PRI值越小越快被执行,那么加入nice值后,将会使得PRI变为:PRI(new)=PRI(old)+nice 。
  • 这样,当nice值为负值的时候,那么该程序将会优先级值将变小,即其优先级会变高,则其越快被执行 。
  • 所以,调整进程优先级,在Linux下,就是调整进程nice值 。
  • nice其取值范围是-20至19,一共40个级别。
  • 需要强调一点的是,进程的nice值不是进程的优先级,他们不是一个概念,但是进程nice值会影响到进程的优先级变化。
  • 可以理解nice值是进程优先级的修正修正数据。
  • 1.3 竞争 独立 并行 并发

  • 竞争性: 系统进程数目众多,而CPU资源只有少量,甚至1个,所以进程之间是具有竞争属性的。为了高效完成任务,更合理竞争相关资源,便具有了优先级
  • 独立性: 多进程运行,需要独享各种资源,多进程运行期间互不干扰
  • 并行: 多个进程在多个CPU下分别,同时进行运行,这称之为并行
  • 并发: 多个进程在一个CPU下采用进程切换的方式,在一段时间之内,让多个进程都得以推进,称之为并发
  • 2.环境变量

    2.1 基本概念

  • 环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数。
  • 如:我们在编写C/C++代码的时候,在链接的时候,从来不知道我们的所链接的动态静态库在那里,但是照样可以链接成功,生成可执行程序,原因就是有相关环境变量帮助编译器进行查找。
  • 环境变量通常具有某些特殊用途,还有在系统当中通常具有全局特性。
  • 2.2 环境变量的引入

    首先我们继续使用刚才的c语言程序,现在有一个问题,我们为什么每次执行代码的时候,都要带上./ 为什么不能像基本指令一样直接执行呢?直接执行可执行程序会爆出命令找不到。而这就跟环境变量有关。系统中是存在相关的环境变量的,保存了程序的程序的搜索路径。

    [ Linux ] 进程优先级 和 环境变量_#include_09

    Linux查看环境变量的方式是输入指令

    env

    [ Linux ] 进程优先级 和 环境变量_#include_10

    而win中也是存在环境变量的,在高级系统设置中我们就可以查看环境变量,如果配置过java环境的同学一定不陌生。

    [ Linux ] 进程优先级 和 环境变量_#include_11

    而这里我们自己写的程序,为什么就找不到呢?

    这是因为系统中搜索可执行程序的环境变量叫做PATH.

    我们来查看一下PATH(每个人的PATH都可能不同)

    env | grep PATH

    [ Linux ] 进程优先级 和 环境变量_优先级_12

    我们想要显示PATH的内容使用如下指令

    echo $PATH

    [ Linux ] 进程优先级 和 环境变量_#include_13

    这里环境变量PATH里面会承载多个路径,中间用 :作为分隔符,比如我们输入基本指令,系统会从PATH环境变量中一个路径一个路径进行查找,直到找到该指令或者不存在,此路径就作为改指令的搜索路径。其中ls等进本指令都在/usr/bin 路径下,而我们的myproc不在该路径下,因此当我们输入myproc的时候系统会提示找不到该指令

    [ Linux ] 进程优先级 和 环境变量_优先级_14

    2.3 环境变量的修改

    如果我们就要输入myproc时运行该程序,我们有3中方法。

    2.3.1 把可执行程序拷入系统路径中

    我们要拷贝到系统路径要是用root权限,假设我们要将myproc拷入/usr/bin路径下

    sudo cp myproc /usr/bin/

    ls /usr/bin/myproc

    [ Linux ] 进程优先级 和 环境变量_优先级_15

    此时我们直接输入myproc,,就可以达到我们的目的

    [ Linux ] 进程优先级 和 环境变量_优先级_16

    但是我们不建议做,因为会污染Linux命令池

    删除 之后,我们此时再运行发现查找不到了

    sudo rm /usr/bin/myproc

    [ Linux ] 进程优先级 和 环境变量_优先级_17


    2.3.2 把当前所处的路径添加到环境变量

    我们在进行这个操作前我们介绍一下我们在Linux命令行中定义的变量,可以定义本地变量,但是他并不会以环境变量的形式存在。

    aaaa=123
    echo $aaaa

    [ Linux ] 进程优先级 和 环境变量_优先级_18


    env | grep aaaa

    [ Linux ] 进程优先级 和 环境变量_#include_19


    如果想让这个变量定义为环境变量我们要这样写,export叫做导出环境变量

    export bbbb=123456
    env | grep bbbb

    [ Linux ] 进程优先级 和 环境变量_优先级_20

    总结:

    我们在命令行中定义的变量,第一种叫做普通变量。第二种叫做环境变量,环境变量具有全局属性。


    此时我们会导环境环境变量了,我们将我们当前路径导入到环境变量中

    pwd 查看当前环境变量
    export PATH=$PATH:/home/Lxy/code/linux-code/9-28

    [ Linux ] 进程优先级 和 环境变量_环境变量_21

    此时添加完之后,我们发现PATH路径添加了我们的myproc这条路径,之后我们输入myproc就可以直接运行程序了

    [ Linux ] 进程优先级 和 环境变量_优先级_22


    3.常见环境变量

    接下来我们将着重介绍了解一下env下的环境变量

  • PATH : 指定命令的搜索路径
  • HOME : 指定用户的主工作目录(即用户登陆到Linux系统中时,默认的目录)
  • SHELL : 当前Shell,它的值通常是/bin/bash。
  • [ Linux ] 进程优先级 和 环境变量_环境变量_23

    history

    [ Linux ] 进程优先级 和 环境变量_优先级_24

    我们发现最大指令3000条

    [ Linux ] 进程优先级 和 环境变量_#include_25


    user

    [ Linux ] 进程优先级 和 环境变量_环境变量_26


    其他内容

    [ Linux ] 进程优先级 和 环境变量_优先级_27


    4.环境变量的获取

    这里我们将介绍通过代码获取环境变量

    4.1命令行的第三个参数

    首先,大家知道main函数中有参数吗,有几个参数?

    答案是有,有3个参数

    首先我们先介绍main函数中的前两个参数,第一个参数是 argc 表示argv数组的个数。第二个参数是一个指针数组,这个数组里面放的什么呢?我们首先来看看结果[for循环初始化声明仅在c99下允许 因此编译时带上 -std=c99]

    #include <stdio.h>
    #include <unistd.h>
    int main(int argc,char* argv[])
    {
    //char* argv[]:什么类型?里面放什么呢?
    for(int i = 0; i < argc , ++i)
    {
    printf("argv[%d]:%s\n",i,argv[i]);
    }

    //printf("hello\n");
    return 0;
    }

    [ Linux ] 进程优先级 和 环境变量_#include_28

    当我们进行命令行输入时,./myproc叫做可执行程序 -a -b -c -d等等这些叫做选项。这些都是字符串,都存在argv这个指针数组中。我们给main函数传递的argc,char* argv[],命令行参数传递的是命令行中输入的程序名和选项!!那意义是什么呢?

    [ Linux ] 进程优先级 和 环境变量_#include_29

    我们知道了这两个参数 我们可以写一个最简单的计算器程序

    #include <stdio.h>
    #include <unistd.h>
    #include <string.h>
    // -a 加法
    // -s 减法
    int main(int argc,char *argv[])
    {
    if(argc != 4)
    {
    printf("Usage: %s [-a|-s|-m|-d] one_data two_data\n", argv[0]);
    return 0;
    }
    int x = atoi(argv[2]);
    int y = atoi(argv[3]);
    if(strcmp("-a", argv[1]) ==0)
    {
    printf("%d+%d=%d\n",x, y, x + y);
    }
    else if(strcmp("-s", argv[1]) ==0)
    {
    printf("%d-%d=%d\n",x, y, x - y);
    }
    else if(strcmp("-m", argv[1]) ==0)
    {
    printf("%d*%d=%d\n",x, y, x * y);
    }
    else if(strcmp("-d", argv[1]) ==0 && y != 0)
    {
    printf("%d/%d=%d\n",x, y, x / y);
    }
    else
    {
    printf("Usage: %s [-a|-s|-m|-d] one_data two_data\n", argv[0]);
    }
    return 0;
    }

    [ Linux ] 进程优先级 和 环境变量_#include_30


    意义:

    因此,这两个参数最大的意义是同一个程序,通过传递不同的参数,让同一个程序有不同的执行逻辑,执行结果。这也是我们平时使用的 ls -a ls -l ,这就是Linux系统中会根据不同的选项,让不同的命令,有不同的表现,指令中那么多选项的由来和起作用的方式。

    在win系统的也是存在这样的 cmd

    [ Linux ] 进程优先级 和 环境变量_环境变量_31


    main的第三个参数

    man函数是可以带第三个参数的!这第三个参数正是环境变量

    int main(int argc,char *argv[],char *env[])
    {
    for(int i = 0;env[i];i++)
    {
    printf("env[%d]:%s\n",i,env[i]);
    }
    return 0;
    }

    [ Linux ] 进程优先级 和 环境变量_环境变量_32

    程序输出结果

    [ Linux ] 进程优先级 和 环境变量_环境变量_33

    env查看环境变量

    [ Linux ] 进程优先级 和 环境变量_优先级_34


    结论:一个进程会被传入环境变量参数的!!


    4.2 通过第三方变量environ获取

    我们也可以使用第三方变量environ获取

    我们可以通过man手册查看一下environ,是C语言给我提供的一个全局变量。

    libc中定义的全局变量environ指向环境变量表,environ没有包含在任何头文件中,所以在使用时 要用extern声明。

    [ Linux ] 进程优先级 和 环境变量_环境变量_35

    #include <stdio.h>
    #include <unistd.h>
    #include <string.h>
    #include <stdlib.h>
    int main(int argc,char *argv[])
    {
    extern char ** environ;
    int i = 0;
    for(;environ[i];i++)
    {
    printf("%s\n",environ[i]);
    }

    [ Linux ] 进程优先级 和 环境变量_优先级_36


    4.3 通过系统调用获取或设置环境变量

    • getenv
    • putenv
    #include <stdio.h>
    #include <stdlib.h>
    int main(int argc,char *argv[])
    {
    printf("%s\n",getenv("PATH"));
    return 0;
    }


    [ Linux ] 进程优先级 和 环境变量_环境变量_37


    (本篇完)

    上一篇:【9.24-9.30】博客精彩回顾
    下一篇:没有了
    网友评论