本文将从以下方面来理解进程:

1.进程的概念 / 什么是进程。

2.如何查看进程

3.进程状态 / 状态修改

4.进程的优先级

5.环境变量

 

 

一.进程的概念 / 什么是进程

      1.通俗来说,进程就是正在运行的一个程序。

      2.内核观点:担当分配系统资源(CPU时间,内存)的实体

      3.操作系统的角度来说,进程描述为一个结构体---->PCB(在Linux下PCB位task_struct)

      4.进程的创建是有限的

(1.)那么有人可能要问了task_struct是什么???

                他是Linux内核的一种数据结构,他会被装载到RAM(内存)里并且包含着进程的信息

(2.)task_struct的内容分配

  • 标示符:描述本进程的唯一标示符,用来区别其他进程
  • 状态:任务状态,退出代码,退出信号等
  • 优先级:相对于其他进程的优先级
  • 程序计数器:程序中即将被执行的下一条指令的地址
  • 内存指针:包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针
  • 上下文数据:进程执行时处理器的寄存器中的数据
  • I/O状态信息:包括显示的I/O请求,分配给进程的I/O设备和被进程使用的文件列表
  • 记账信息:可能包括处理器时间总和,使用的时钟数总和,时间限制,记账号等
  • 其他信息

二.如何查看进程

//1.查看所有进程
ls /proc/


//2.查看指定进程(例如要查看PID为1的进程信息)
ls /proc/1

//3.查看一个运行程序的个进程(这里用到了管道后边会讲)
ps aux | grep test | grep -v grep

我们可以通过系统调用来获取进程标识符:

  • 进程id:PID
  • 父进程id:PPID
  1 #include<stdio.h>
  2 #include<unistd.h>
  3 
  4 int main()
  5 {
  6 
  7 printf("pid-> %d\n",getpid());
  8 printf("ppid-> %d\n",getpid());
  9 
 10 return 0;
 11 }

以上是获取进程id的实现代码

三.进程状态 / 状态修改

1.进程的七大状态:(linux内核里有时候也叫任务)

  • R--->运行状态
  • S--->睡眠状态(可中断睡眠状态)
  • D--->磁盘休眠状态(不可中断睡眠状态)
  • T--->停止状态
  • X--->死亡状态
  • t --->追踪状态
  • Z--->僵尸状态(很重要,必须理解)

2.修改进程状态

 

我们可以通过以下方式修改进程状态:

kill -SIGSTOP pid

3.僵尸进程(很重要!!!很重要!!!很重要!!!)

(1.)什么是僵尸进程????

  • 子进程先退出,父进程后退出
  • 子进程退出为了保存退出状态,因此这个子进程退出后的资源不会被完全释放,他必须等待父进程接收到他的退出状态,让父进程来子进程释放资源
  • 如果父进程不管不问子进程,那么这个时候子进程就变成了僵尸进程,占用着系统资源不释放

在这里我是这样记忆,父进程就像是子进程的后妈,虽然是名义上的妈,但是对于子进程是不管不顾,不问其死活的

(2.)僵尸进程的危害:

  • 内存泄漏
  • 进程的退出状态必须被维持下去,因为他要告诉父进程,你交给我的任务我完成的怎么样,如果父进程不管不顾,那么子进程就一直维持在僵尸状态
  • 维护退出状态本身就是要用数据维护,也属于进程基本信息,所以保存在PCB中,换句话说,僵尸状态一直不退出,PCB就要一直维护
  • 如果父进程创建了很多子进程就是不收回会造成内存资源浪费

4.孤儿进程

      父进程先退出,但是子进程被init进程领养,那么这时候的子进程就是孤儿进程。他的资源也由init进程回收释放

四.进程的优先级

 (1.)概念

  • CPU分配资源的先后顺序,就是进程的优先级
  • 优先级高的进程有优先执行的权力,配置进程优先权对于多任务环境的Linux下有很大的好处,可以改善系统性能
  • 还可以把进程运行到指定的CPU上,这样一来可以把不重要的进程安排到某个CPU上可以大大改善系统的性能

 (2.)如何查看进程的优先级

//查看进程的优先级命令
ps -l

             

我们可以看到以上的信息:

  • UID:代表执行者的身份
  • PID:代表进程的id
  • PPID:代表父进程id
  • PRI:代表正在执行的进程的优先级,该值越小优先级越高,越早被执行
  • NI:代表这个进程的nice值

这里我们可以看到NI(nice)值,这个nice值我们称之为进程优先级的可修正数据所以:

PRI = PRI  + NI(nice)

这里当NI为负数时,PRI最小及优先级最高

nice的取值范围是 19 ~ -20,一共四十个级别

   (3.)进程优先级的修改

            这是通过修改(NI)nice值来修改进程的优先级

          1.nice命令

nice -n -5 ./test

            这条命令是进程启动前进行修改

          2.renice命令          

//PID为4800的进程NI(nice)值设置为5
renice -5 -p 4800

            这条命令是进程启后进行修改

         3.利用top命令

           top---->输入 r ---->输入 PID ---->输入要修改为多少的nice值

     (4.)其他概念:

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

  五.环境变量

        环境变量通常具有全局属性(可以被子进程继承下去)

  • PATH*:指定命令的搜索路径
  • HOME*:指定用户的主工作目录(即用户登陆到Linux系统中时,默认的目录)
  • HISTSIZE*:指保存历史命令记录的条数
  • SHELL*:当前Shell,它的值通常是/bin/bash

(1.)如何查看环境变量???

        1.直接用命令

//这里的name是环境变量的名称
echo $name

        2.main函数的第三个参数

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

        这里就不截图运行后的结果了,大家还是自己多动手!!!

在这里补充说一下main函数的三个参数的含义:

  • argc:程序有几个命令行参数
  • argv:用于存储这个参数
  • env:用于存储环境变量

        3.通过第三方变量environ获取

1 #include<stdio.h>
  2 
  3 int main(int argc,char *argv[])
  4 {
  5 
  6         extern char **environ;
  7         int i = 0;
  8         for(; environ[i];i++)
  9         {
 10                 printf("%s\n",environ[i]);
 11         }
 12 
 13 
 14         return 0;
 15 }

        4.调用getenv/putenv

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 int main()
  4 {
  5 
  6 printf("%s\n",getenv("PATH"));
  7 
  8         return 0;
  9 }

常用putenv和getenv来访问特定的环境变量

(2.)和环境变量相关的指令

  • echo:显示某个环境变量
  • export:设置一个新的环境变量
  • env:显示所有环境变量
  • unset:清楚环境变量
  • set:显示本地定义的shell变量和环境变量

(3.)环境变量的组织方式

我们可以看到每一个程序都会收到一张环境表,环境表是一个字符指针数组,每个指针数组指向一个以 \0 结尾的环境字符串

 

 

Logo

更多推荐