【Linux】进程的优先级&&环境变量,Linux,进程优先级与环境变量详解

马肤

温馨提示:这篇文章已超过434天没有更新,请注意相关的内容是否还可用!

摘要:,,本文简要介绍了Linux系统中进程的优先级和环境变量的概念。进程优先级决定了进程在处理任务时的顺序,通过调整优先级,可以影响系统的性能。环境变量是操作系统中用于存储和传递用户环境信息的变量,它们对进程的行为和性能也有重要影响。了解进程的优先级和环境变量的设置和使用,对于优化Linux系统性能和提高工作效率至关重要。

个人主页 : zxctscl

如有转载请先通知

文章目录

  • 1. 前言
  • 2. 进程的优先级
    • 2.1 什么是优先级
    • 2.2 为什么要有优先级
    • 2.3 优先级的查看方式
    • 2.4 对优先级调整
    • 3. 命令行参数
    • 4. 环境变量
      • 4.1 环境变量与配置文件
        • 4.1.1 环境变量初步介绍
        • 4.1.2 配置文件
        • 4.2 更多环境变量
        • 4.3 整体理解环境变量与系统
        • 4.4 环境变量的特性

          1. 前言

          上一篇在进程中提到了 【Linux】进程状态&&僵尸进程和孤儿进程&&阻塞、挂起和运行,这次来继续来谈进程。

          2. 进程的优先级

          2.1 什么是优先级

          在进程的PCB中存在一个进程的优先级,那么什么是进程的优先级?

          进程的优先级就是指定一个进程获取某种资源的顺序。

          进程中使用task_struct进程控制块结构体中的内部字段用一个整型prio表示优先级。

          Linux中优先级数字越小,优先级越高。

          比较一下优先级和权限:权限决定一件事能不能做,而有优先级就表示一件事情能做只是代表获取资源的顺序。

          2.2 为什么要有优先级

          因为进程访问的资源(CPU)时有限的,系统中进程大部分情况都是有较多的。

          就像打游戏时候,键盘、鼠标等硬件只有一套,不同的进程本质上对系统硬件资源本来就是通过操作系统方式来实现资源的共享。

          更形象就像在下课高峰期,食堂买饭要排队。

          操作系统关于调度和优先级的原则:分时操作系统,要保证基本的公平。如果进程因为长时间不被调度,就造成了饥饿问题。

          2.3 优先级的查看方式

          为了方便查看,先用C语言写测试代码:

          Makefile:

            1 myprocess:myprocess.c
            2   gcc -o $@ $^ 
            3 .PHONY:clean
            4 clean:
            5   rm -f myprocess
          

          myprocess.c:

            1 #include
            2 #include
            3
            4 int main()
            5 {
            6   while(1)
            7   {
            8     printf("I am a process,pid:%d\n",getpid());
            9     sleep(1);
           10   }
           11 }
          

          在Linux中查看优先级的方式用到命令:

          ps -al
          

          【Linux】进程的优先级&&环境变量,Linux,进程优先级与环境变量详解 第1张

          PRI:进程的优先级

          NI:进程优先级的修正数据,N是nice值。新的优先级=优先级+nice值,达到对于进程优先级动态修改的过程。

          UID : 代表执行者的身份

          PID : 代表这个进程的代号

          PPID :代表这个进程是由哪个进程发展衍生而来的,亦即父进程的代号

          2.4 对优先级调整

          改之前的NI:

          【Linux】进程的优先级&&环境变量,Linux,进程优先级与环境变量详解 第2张

          想要对进程优先级调整就想要用到命令:

          top
          

          【Linux】进程的优先级&&环境变量,Linux,进程优先级与环境变量详解 第3张

          然后输入:r

          【Linux】进程的优先级&&环境变量,Linux,进程优先级与环境变量详解 第4张

          再输入进程的pid:

          【Linux】进程的优先级&&环境变量,Linux,进程优先级与环境变量详解 第5张

          最后输入要修改的nice值:

          先修改为100:

          【Linux】进程的优先级&&环境变量,Linux,进程优先级与环境变量详解 第6张

          再来查看一下这个进程的NI:

          【Linux】进程的优先级&&环境变量,Linux,进程优先级与环境变量详解 第7张

          所以说:nice值不能让用户任意调整,而是有范围的,如果随便写就有可能使操作系统调度出现不平衡,必须在可控范围内调整。

          nice其取值范围是-20至19,一共40个级别。

          【Linux】进程的优先级&&环境变量,Linux,进程优先级与环境变量详解 第8张

          当再想要修改nice值的时候,就不能修改了,普通用户不能频繁修改nice值,把账号先切换为root,再把nice值修改为-10:

          此时PRI就变为了70:

          【Linux】进程的优先级&&环境变量,Linux,进程优先级与环境变量详解 第9张

          每次调整优先级PRI都是从80开始范围是从60到99

          新的优先级=优先级+nice值

          一般不推荐用户调整进程的优先级

          【Linux】进程的优先级&&环境变量,Linux,进程优先级与环境变量详解 第10张

          竞争性: 系统进程数目众多,而CPU资源只有少量,甚至1个,所以进程之间是具有竞争属性的。为了高效完成任务,更合理竞争相关资源,便具有了优先级

          独立性: 多进程运行,需要独享各种资源,多进程运行期间互不干扰

          并行: 多个进程在多个CPU下分别,同时进行运行,这称之为并行

          并发: 多个进程在一个CPU下采用进程切换的方式,在一段时间之内,让多个进程都得以推进,称之为并发。

          3. 命令行参数

          在C语言中会出现main函数带参的情况。

          像:

          int main(int argc,char *argv[])
          {}
          

          main函数的参数可以带可不带。

          这些参数

          在Linux里面写一个测试代码:

            1 #include
            2 #include
            3
            4 int main(int argc,char *argv[])
            5 {
            6   int i;
            7   for(i=0;i
            9     printf("argv[%d]-%s\n",i,argv[i]);
           10   }
           11 }
          

          argc表示数组中元素的个数,argv[]是一个指针数组。

          如果直接执行程序不带参数,那么默认argv[0]执行的就是执行的程序,而且就是有它一个。

          如果带1参数,会自动在将参数变成2个,0号下标指向执行的程序,1号下标就只向这个参数。

          【Linux】进程的优先级&&环境变量,Linux,进程优先级与环境变量详解 第11张

          这就是命令行字符串。

          【Linux】进程的优先级&&环境变量,Linux,进程优先级与环境变量详解 第12张

          这里的argv是一个变成数组,把命令行字符串以空格为分隔符放在argv里面,下标与输入顺序匹配。再将这些以参数的形式传给了main函数,有几个这样的字符串,那么argc就是几。argv数组最后必须以NULL结尾。

          【Linux】进程的优先级&&环境变量,Linux,进程优先级与环境变量详解 第13张

          修改一下代码:

            1 #include
            2 #include
            3 #include
            4
            5 int main(int argc,char *argv[])
            6 {
            7   if(argc!=2)
            8   {
            9     printf("Usage: %s -[a,b,c,d]\n",argv[0]);
           10     return 1;
           11   }
           12
           13   if(strcmp(argv[1],"-a")==0)
           14   {
           15     printf("this is function1\n");
           16   }
           17
           18   else if(strcmp(argv[2],"-b")==0)
           19   {
           20     printf("this is function2\n");
           21   }
           22
           23   else if(strcmp(argv[3],"-c")==0)
           24   {
           25     printf("this is function3\n");
           26   }
           27
           28   else if(strcmp(argv[4],"-d")==0)
           29   {
           30     printf("this is function4\n");
           31   }
           32   else{
           33   printf("no this function\n");
           34   }
           35 }
           36
          

          编译运行一下,发现必须要带选项,那就带上:

          【Linux】进程的优先级&&环境变量,Linux,进程优先级与环境变量详解 第14张

          同一个程序可以通过不同的选项来执行同一个程序内的不同的功能。

          就像是ls带不同选项,功能不一样:

          【Linux】进程的优先级&&环境变量,Linux,进程优先级与环境变量详解 第15张

          命令行参数本质交给我们程序的不同选项,用来定制不同的程序功能。命令中就会携带很多的选项。

          【Linux】进程的优先级&&环境变量,Linux,进程优先级与环境变量详解 第16张

          写一个父子进程的代码:

            1 #include
            2 #include
            3 #include
            4
            5 int g_val=100000;
            6
            7 int main()
            8 {
            9   printf("I am a father process,pid:%d,ppid:%d,g_val:%d\n",getpid(),getppid(),g_val);
           10   sleep(5);
           11
           12   pid_t id=fork();
           13   if(id==0)
           14   {
           15     while(1)
           16     {
           17      printf("I am a child process,pid:%d,ppid:%d,g_val:%d\n",getpid(),getppid(),g_val);
           18      sleep(1);
           19
           20     }
           21   }
           22   else
           23   {
           24   while(1)
           25   {
           26   printf("I am a father process,pid:%d,ppid:%d,g_val:%d\n",getpid(),getppid(),g_val);
           27   sleep(1);
           28
           29   }
           30 }
           31 }
          

          编译运行:

          【Linux】进程的优先级&&环境变量,Linux,进程优先级与环境变量详解 第17张

          发现父进程的数据,默认能被子进程看到并访问。

          父进程的ppid是谁的?

          再修改一下代码:把创建子进程的代码注释

          【Linux】进程的优先级&&环境变量,Linux,进程优先级与环境变量详解 第18张

          再编译运行一下:

          发现这个ppid还是24361

          【Linux】进程的优先级&&环境变量,Linux,进程优先级与环境变量详解 第19张

          查看一下:

          发现它是bash

          【Linux】进程的优先级&&环境变量,Linux,进程优先级与环境变量详解 第20张

          当把代码改回之前的:

          【Linux】进程的优先级&&环境变量,Linux,进程优先级与环境变量详解 第21张

          然后重新编译运行:发现ppid还是24361,还是bash:

          【Linux】进程的优先级&&环境变量,Linux,进程优先级与环境变量详解 第22张

          说明命令行中启动的程序,都会变成进程,其实都是bash的子进程。输入的命令行字符串,默认是输入给父进程bash的。

          就像ls,本身也是一个可执行程序,启动它就和启动自己写的程序是一样的

          【Linux】进程的优先级&&环境变量,Linux,进程优先级与环境变量详解 第23张

          4. 环境变量

          4.1 环境变量与配置文件

          4.1.1 环境变量初步介绍

          为什么执行自己写的程序时候要带路径:

          【Linux】进程的优先级&&环境变量,Linux,进程优先级与环境变量详解 第24张

          而ls就不需要:

          【Linux】进程的优先级&&环境变量,Linux,进程优先级与环境变量详解 第25张

          也可以带路径执行:

          【Linux】进程的优先级&&环境变量,Linux,进程优先级与环境变量详解 第26张

          这个主要是因为在Linux系统中,存在一些全局的设置,表明,告诉命令行解释器,应该去哪些路径下去寻找可执行程序。

          这些设置在PATH里面保存,查看的话就用:

          echo $PATH
          

          【Linux】进程的优先级&&环境变量,Linux,进程优先级与环境变量详解 第27张

          系统中很多配置,在我们登录Linux系统的时候,就已经被加载到bash进程中,而bash进程就在内存中。

          PATH:环境变量

          要打印环境变量的内容用:$PATH

          bash在执行命令的时候,想要先找到命令,因为未来要加载。

          命令会在对应的路径下找,如果没有找到就报:

          【Linux】进程的优先级&&环境变量,Linux,进程优先级与环境变量详解 第28张

          如果找到了就会加载并运行这个程序:

          【Linux】进程的优先级&&环境变量,Linux,进程优先级与环境变量详解 第29张

          【Linux】进程的优先级&&环境变量,Linux,进程优先级与环境变量详解 第30张

          如果不加路径来执行myprocess会报:找不到

          【Linux】进程的优先级&&环境变量,Linux,进程优先级与环境变量详解 第31张

          如果需要把自己写的程序执行和系统的一样,可以可执行程序添加到bash路径下:

          【Linux】进程的优先级&&环境变量,Linux,进程优先级与环境变量详解 第32张

          但是一些命令就不能了,PATH里面就只剩下刚才加的路径:

          【Linux】进程的优先级&&环境变量,Linux,进程优先级与环境变量详解 第33张

          因为对环境变量直接赋值,就相当于把环境变量直接覆盖了

          自己写的程序到是可以直接运行了:

          【Linux】进程的优先级&&环境变量,Linux,进程优先级与环境变量详解 第34张

          直接重新登录就可以了:

          此时路径又回来了,刚才设置的环境变量就没有了

          【Linux】进程的优先级&&环境变量,Linux,进程优先级与环境变量详解 第35张

          默认我们查到的环境变量是内存级的。

          不用覆盖,怎么添加环境变量:

          用:

          PATH=$PATH:路径
          

          【Linux】进程的优先级&&环境变量,Linux,进程优先级与环境变量详解 第36张

          此时再查看环境变量时候:这个环境变量就有了

          【Linux】进程的优先级&&环境变量,Linux,进程优先级与环境变量详解 第37张

          再执行程序的时候带不带路径都可以:

          【Linux】进程的优先级&&环境变量,Linux,进程优先级与环境变量详解 第38张

          4.1.2 配置文件

          最开始的环境变量不是在内存中,而是在系统对应的配置文件中,用户在登录时候,会创建一个bash进程,此时bash就会读取配置文件,就会把配置文件里面的环境变量在bash里面拷贝一份。

          这就是为什么重新登陆的时候之前在PATH加到就不存在了,因为配置文件没有改。

          这个配置文件在哪里呢?

          切换到家目录下,有与配置文件有关的文件:.bash_profile、.bashrc还有/etc/bashrc

          【Linux】进程的优先级&&环境变量,Linux,进程优先级与环境变量详解 第39张

          打开.bash_profile:

          【Linux】进程的优先级&&环境变量,Linux,进程优先级与环境变量详解 第40张

          环境变量默认是在配置文件里面的。

          打开.bash_profile后把路径加上去:

          【Linux】进程的优先级&&环境变量,Linux,进程优先级与环境变量详解 第41张

          此时不加路径也可以运行:

          【Linux】进程的优先级&&环境变量,Linux,进程优先级与环境变量详解 第42张

          程序登陆:不加路径还是可以运行

          【Linux】进程的优先级&&环境变量,Linux,进程优先级与环境变量详解 第43张

          4.2 更多环境变量

          用env可以查看其他环境变量

          【Linux】进程的优先级&&环境变量,Linux,进程优先级与环境变量详解 第44张

          来看看PWD:

          会随着路径变化,把当前路径会记录在PWD的环境变量中:

          【Linux】进程的优先级&&环境变量,Linux,进程优先级与环境变量详解 第45张

          系统启动的时候会把改程序的shell运行起来,这就有了命令行解释器:

          【Linux】进程的优先级&&环境变量,Linux,进程优先级与环境变量详解 第46张

          曾经输入的命令是记录下来的,不可能全部都记住,HISTSIZE默认记录新的3000条历史命令

          【Linux】进程的优先级&&环境变量,Linux,进程优先级与环境变量详解 第47张

          用history可以查看历史命令:

          【Linux】进程的优先级&&环境变量,Linux,进程优先级与环境变量详解 第48张

          是目前维护历史命令的数目:

          【Linux】进程的优先级&&环境变量,Linux,进程优先级与环境变量详解 第49张

          这些环境变量是在用户登陆的时候系统自动加载的:

          【Linux】进程的优先级&&环境变量,Linux,进程优先级与环境变量详解 第50张

          【Linux】进程的优先级&&环境变量,Linux,进程优先级与环境变量详解 第51张

          我们可以自己导入环境变量:

          export THIS_IS_MY_ENV=value
          

          【Linux】进程的优先级&&环境变量,Linux,进程优先级与环境变量详解 第52张

          此时就存在了这个环境变量:

          【Linux】进程的优先级&&环境变量,Linux,进程优先级与环境变量详解 第53张

          取消环境变量:

          unset THIS_IS_MY_ENV
          

          此时就查不到了:

          【Linux】进程的优先级&&环境变量,Linux,进程优先级与环境变量详解 第54张

          【Linux】进程的优先级&&环境变量,Linux,进程优先级与环境变量详解 第55张

          当加环境变量时候不加export,直接写,不会报错:

          也可以查出来

          【Linux】进程的优先级&&环境变量,Linux,进程优先级与环境变量详解 第56张

          这种变量叫做本地变量。

          4.3 整体理解环境变量与系统

          先来写一个获取环境变量的测试代码:

            1 #include
            2 #include
            3 #include
            4
            5
            6 int main()
            7 {
            8   extern char** environ;
            9   int i;
           10   for(i=0;environ[i];i++)
           11   {
           12     printf("env[%d]->%s\n",i,environ[i]);
           13   }
           14 }
          

          【Linux】进程的优先级&&环境变量,Linux,进程优先级与环境变量详解 第57张

          这些环境变量就是和用env指令查到的一样。

          环境变量默认也是可以被子进程拿到的,就说明本身不在子进程里面,而环境变量们默认是在bash内部。

          解释一下代码:

          【Linux】进程的优先级&&环境变量,Linux,进程优先级与环境变量详解 第58张

          在磁盘中:有系统级的配置文件,有全局的也有当前进程的,还包含了环境变量。

          在内存中:当有一天我们登陆时,就会在内存中给当前用户创建一个进程,就是bash/shell,登陆的时候把这些配置文件信息就加载到bash内部。

          所有环境变量的数据都在bash里面。

          环境变量有变量名有变量内容,环境变量的本质就是数据。当启动我们自己的程序时,就会在内存中创建一个子进程./myprocess,而父进程的数据,默认能被子进程看到并访问,环境变量是全局的。

          环境变量如此多,那么在bash内部如何组织环境变量?

          实际上bash在启动的时候,会维护一张表,这张表是一个指针数组char *env[],指向内容全是char*的。每当有一个环境变量,像PATH=/usr/bin:a/b/c…,也就是字符串,环境变量就可以把对应的字符串从配置文件加载过来,配置信息就有了。把环境变量的地址填到环境变量表里面,这个环境变量就纳入到了bash里面。每一个环境变量都是字符串等于内容,最后在以NULL结尾。

          bash进程在启动的时候,默认会给我子进程的两张表:argv[]命令行参数表,env[]环境变量表。bash通过各种方式交给子进程。argv[]命令行参数表来自用户输入的命令行;env[]环境变量表从配置文件来。

          系统为了方便用户找到环境变量表, 就提供了extern char **environ指针就能被全局看到。就可以用[]来访问指针字符串的内容。

          【Linux】进程的优先级&&环境变量,Linux,进程优先级与环境变量详解 第59张

          【Linux】进程的优先级&&环境变量,Linux,进程优先级与环境变量详解 第60张

          还可以在main函数里面加三个参数来获取环境变量:

              1 #include
              2 #include
              3 #include
              4
              5
              6 int main(int argc,char *argv[],char *env[])
              7 {
              8   int i;
              9   for(i=0;env[i];i++)
             10   {
             11     printf("env[%d]->%s\n",i,env[i]);
             12   }
             13 }
          

          编译运行:

          【Linux】进程的优先级&&环境变量,Linux,进程优先级与环境变量详解 第61张

          【Linux】进程的优先级&&环境变量,Linux,进程优先级与环境变量详解 第62张

          exoprt导环境变量本质上就是在env[]环境变量表中找到一个没有被使用的位置,然后把它指向对应的环境变量。导环境变量就是把字符串添加到表里。

          4.4 环境变量的特性

          环境变量具有系统级的全局属性,因为环境变量本身会被子进程继承。

          系统刚开始启动时候,启动了bash,bash可以启动很多进程,进程可以继续通过代码创建子进程。但是不管有多少给子进程,bash都能拿到所有子进程对应的环境变量,也就是环境变量具有系统级的全局属性。

          系统中还存在getenv,可以根据环境变量直接拿到环境变量的内容,可以单个获取环境变量的内容。

          【Linux】进程的优先级&&环境变量,Linux,进程优先级与环境变量详解 第63张

          putenv就是用来导环境变量

          【Linux】进程的优先级&&环境变量,Linux,进程优先级与环境变量详解 第64张

          用代码来获取一下:

              1 #include
              2 #include
              3 #include
              4 #include
              5
              6 int main(int argc,char *argv[],char *env[])
              7 {
              8  char *path=getenv("PATH");
              9  if(path==NULL)return 1;
             10  printf("path:%s\n",path);
             11 }
          

          编译运行之后,就可以单独获取PATH一个环境变量了:

          【Linux】进程的优先级&&环境变量,Linux,进程优先级与环境变量详解 第65张

          获取环境变量的三种方式:

          1. extern char **environ;
          2. 通过main函数参数
          3. getenv(“path”);

          【Linux】进程的优先级&&环境变量,Linux,进程优先级与环境变量详解 第66张

          用export导的环境变量也会创建子进程吗?

          【Linux】进程的优先级&&环境变量,Linux,进程优先级与环境变量详解 第67张

          并不是,export导的环境变量不会创建子进程。它是内建命令。

          在Linux中百分之八十的美丽都是bash创建子进程执行的。还有一些命令是由bash自己亲自去执行的。bash也是用c语言写的,就相当于在bash里面有个export()函数,直接函数调用就执行export了。

          把环境变量先清空:

          【Linux】进程的优先级&&环境变量,Linux,进程优先级与环境变量详解 第68张

          再在执行其他命令,能被执行的都是内建命令

          【Linux】进程的优先级&&环境变量,Linux,进程优先级与环境变量详解 第69张

          本地变量只在本bash内部有效,无法被子进程继承下去。导成环境变量,此时才能被获取。

          有问题请指出,大家一起进步!!!


0
收藏0
文章版权声明:除非注明,否则均为VPS857原创文章,转载或复制请以超链接形式并注明出处。

相关阅读

  • 【研发日记】Matlab/Simulink自动生成代码(二)——五种选择结构实现方法,Matlab/Simulink自动生成代码的五种选择结构实现方法(二),Matlab/Simulink自动生成代码的五种选择结构实现方法详解(二)
  • 超级好用的C++实用库之跨平台实用方法,跨平台实用方法的C++实用库超好用指南,C++跨平台实用库使用指南,超好用实用方法集合,C++跨平台实用库超好用指南,方法与技巧集合
  • 【动态规划】斐波那契数列模型(C++),斐波那契数列模型(C++实现与动态规划解析),斐波那契数列模型解析与C++实现(动态规划)
  • 【C++】,string类底层的模拟实现,C++中string类的模拟底层实现探究
  • uniapp 小程序实现微信授权登录(前端和后端),Uniapp小程序实现微信授权登录全流程(前端后端全攻略),Uniapp小程序微信授权登录全流程攻略,前端后端全指南
  • Vue脚手架的安装(保姆级教程),Vue脚手架保姆级安装教程,Vue脚手架保姆级安装指南,Vue脚手架保姆级安装指南,从零开始教你如何安装Vue脚手架
  • 如何在树莓派 Raspberry Pi中本地部署一个web站点并实现无公网IP远程访问,树莓派上本地部署Web站点及无公网IP远程访问指南,树莓派部署Web站点及无公网IP远程访问指南,本地部署与远程访问实践,树莓派部署Web站点及无公网IP远程访问实践指南,树莓派部署Web站点及无公网IP远程访问实践指南,本地部署与远程访问详解,树莓派部署Web站点及无公网IP远程访问实践详解,本地部署与远程访问指南,树莓派部署Web站点及无公网IP远程访问实践详解,本地部署与远程访问指南。
  • vue2技术栈实现AI问答机器人功能(流式与非流式两种接口方法),Vue2技术栈实现AI问答机器人功能,流式与非流式接口方法探究,Vue2技术栈实现AI问答机器人功能,流式与非流式接口方法详解
  • 发表评论

    快捷回复:表情:
    评论列表 (暂无评论,0人围观)

    还没有评论,来说两句吧...

    目录[+]

    取消
    微信二维码
    微信二维码
    支付宝二维码