【Linux】进程与进程状态

目录

一、进程

1.1 基本概念

1.2 PCB

1.3 task_struct 内容分类

二、获取进程标识符

三、fork初识

四、进程状态

4.1 操作系统常见的进程状态

4.2 Linux 系统进程的状态

4.3 运行状态

4.4 休眠状态

4.5 停止状态

4.6 终止状态

4.7 僵尸状态

4.8 孤儿进程


一、进程

1.1 基本概念

  • 程序的一个一次执行过程,正在执行的程序等。
  • 内核观点:担当分配系统资源(CPU时间、内存)的实体。

其实,我们在自己启动一个软件,本质其实就是启动了一个进程。在Linux中,运行一条命令,例如:./a.out 时,其实就是在系统层面创建了一个进程。

Linux是可以同时加载多个程序的,Linux是可能同时存在大量的进程在系统中的(OS,内存)。

那Linux系统是如何管理大量的进程的呢?我们往下看。

1.2 PCB

  • 进程的信息被放在一个叫做进程控制块的数据结构中我,可以理解为进程属性的集合。
  • 我们通常称之为PCB (process control block),linux操作系统下的PCB:Linux中进程控制块PCB-------task_struct结构体结构 - 童嫣 - 博客园 (cnblogs.com)

task_struct——PCB中的一种

  • 在 Linux 中描述进程的结构体叫做 task_struct。
  • task_struct 是 Linux 内核中的一种数据结构,它会被装载到RAM(内存)里并且包含着进程的信息。

1.3 task_struct 内容分类

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

所以,如果操作系统想控制一个进程。就可以根据 task_struct 中记录的各种进程信息对其进行管理。

即对进程的管理,变成了对进程 PCB 结构体链表的增删改查。

现在,我们来看看在 Linux 中如何查看当前正在运行的进程。我们先创建一个进程。

【Linux】进程与进程状态_第1张图片

然后将其运行起来,接下来我们再复制一个窗口,查看当前进程。

 【Linux】进程与进程状态_第2张图片

 【Linux】进程与进程状态_第3张图片

 查找信息如下:

 我们就成功得到 a.out 的进程号为 10578,为了验证确实是我们刚刚运行的进程,接下来我们使用命令将其终止。

【Linux】进程与进程状态_第4张图片

 【Linux】进程与进程状态_第5张图片

我们系统中还存在一个 /proc 目录 将所有的内存级进程以文件系统的形式展现出来,

【Linux】进程与进程状态_第6张图片

 比如我们将上面的进程继续跑起来,然后查看其进程ID

 接下来在 proc 中查看当前该进程

 查看其详细属性数据【Linux】进程与进程状态_第7张图片

二、获取进程标识符

接下来,我们学习一个获取 当前进程id 的系统调用。

【Linux】进程与进程状态_第8张图片

使用非常简单,如下:

【Linux】进程与进程状态_第9张图片

 效果如下:

【Linux】进程与进程状态_第10张图片

 其父进程是 bash 

三、fork初识

创建一个子进程。

【Linux】进程与进程状态_第11张图片

【Linux】进程与进程状态_第12张图片

关于 fork 的三个问题:

  1. 为什么给紫禁城返回0,给父进程返回子进程的 id

为的 是利用父进程区分各个子进程,因为只有一个父进程,而有多个子进程。

     2.父子进程被创建出来,哪个先被执行

不一定!运行顺序是由操作系统决定的

     3.为什么会有两个返回值

因为fork内部 父子进程会执行其各自的 return 语句

 现在我们写一个程序来验证一下fork 函数的功能。

【Linux】进程与进程状态_第13张图片

 以下是运行结果:

【Linux】进程与进程状态_第14张图片

不能发现,ret 居然有两个值,也就是表示 fork 函数返回了两个值。

所以我们通常使用 if 进行分流

【Linux】进程与进程状态_第15张图片

 【Linux】进程与进程状态_第16张图片

 监控起来:

四、进程状态

4.1 操作系统常见的进程状态

  • 新建:创建进程,进程刚被创建。
  • 运行:task_struct 结构体在运行队列中排队,就叫做运行态。
  • 阻塞:等待非CPU资源就绪,阻塞状态。
  • 挂起:当内存不足时,OS通过适当的置换进程的代码和数据到磁盘,进程的状态就成为挂起。

4.2 Linux 系统进程的状态

  • R运行状态(running):并不意味着进程一定在运行中,它表明进程要么是在运行中要么在运行队列里。
  • S睡眠状态(sleeping):意味着进程在等待事件完成(这里的睡眠有时候也叫做可中断睡眠(interruptible sleep))
  • D磁盘休眠状态( Disk sleep) 有时候也叫不可中断睡眠(uninterruptible sleep),在这个状态的进程通常会等待IO的结束。
  • T停止状态(stopped):可以通过发送 SIGSTOP 信号给进程来停止 (T) 进程。这个被暂停的进程可以通过发送 SIGCONT 信号来让进程继续运行。
  • X死亡状态(dead):这个状态只是一个返回状态,你不会在任务列表里看到这个状态。

【Linux】进程与进程状态_第17张图片

4.3 运行状态

首先我们来写一段程序,来了解当前进程的状态是什么样的。

【Linux】进程与进程状态_第18张图片

 运行监控代码:

发现,此时进程处于S状态

因为 printf 是在屏幕上输出,所以当打印时我们会进入阻塞队列,而CPU运行速度很快,导致当前进程大部分时间处于阻塞状态/。  我们大部分时间看到的都是阻塞状态

如果我们将printf语句去掉,再进行监控:

【Linux】进程与进程状态_第19张图片

【Linux】进程与进程状态_第20张图片

 此时状态就变为了 R 状态

而这个+号呢,表示这个进程为前台进程。 

这个前台进程表示,该进程执行时,输入命令是无效的,但能被Ctrl+c终止掉。其实是占用了bash对话框。

 如果我们想让该进程处于后台运行,则可以加上一个取地址运算符。

 此时进程就会在后台运行,而且ctrl+c无法终止。我们可以使用 kill 命令将其终止。

4.4 休眠状态

休眠状态其实分为中断睡眠和不可中断睡眠,像上面我们实现的S状态,就为可中断睡眠状态,而现在这里主要来阐述一下不可中断睡眠(D),

这里举一个场景。

当一个进程正在往磁盘中写入数据时,而此时内存空间不足,操作系统就有可能强行将该正在写入的进程终止,这种情况是绝对不允许的。

所以,此时出现了不可中断状态,即当一个进程正在进行磁盘写入操作时,操作系统无法将该进程终止。这便是不可中断睡眠状态。

4.5 停止状态

在操作系统中,T(stopped)和t(tracing stop)其实都是用大写T来表示,为了做以区分,所以将两种暂停状态分别以不同的形式展示。

T(stopped)状态主要为我们直接使用命令将一个进程进行暂停。

比如下面一个正在运行的进程。我们使用kill -19 停止该进程。

在kill命令中,有19号信号——暂停信号就可以实现该功能。

【Linux】进程与进程状态_第21张图片

 

接下来我们来演示如何使用kill命令实现暂停状态。

现在是一个正在运行的进程。

【Linux】进程与进程状态_第22张图片

然后我们使用kill -19进行暂停。

运行的进程报出提示

【Linux】进程与进程状态_第23张图片

进程监控中:

【Linux】进程与进程状态_第24张图片 然后我们使用kill -18 继续该进程

 

【Linux】进程与进程状态_第25张图片

而 t (sracing stop)通常表示为我们调试过程中的暂停(-g 进入gdg模式)。

【Linux】进程与进程状态_第26张图片

然后我们让程序跑起来( r )

【Linux】进程与进程状态_第27张图片

【Linux】进程与进程状态_第28张图片 【Linux】进程与进程状态_第29张图片

 暂停和休眠状态的区别: 

休眠是在等待某种资源,暂停相当于阻塞状态。

4.6 终止状态

当一个进程即将结束时,此时进程状态就会被置为 X(终止) 状态,此时 CPU 处理到该进程时就会进行进程释放等一系列操作。

这是一个瞬间的执行的状态。因为CPU的速度非常迅速。

4.7 僵尸状态

  • 僵尸状态(Zombies)是一个比较特殊的状态。当进程退出并且父进程没有读取到子进程退出的返回代码时就会产生僵尸进程。
  • 僵尸进程会以终止状态保持在进程表中,并且会一直在等待进程读取退出状态代码。
  • 所以,只要子进程退出,父进程还在运行,但父进程没有读取到子进程的状态,子进程就会进入 Z 状态。

一个进程已经退出,但是还不允许被OS释放,处于一个被检测的状态

比如一个人突然死亡,但是还不能直接进行处理,处于被法医检测的状态。 

维持该状态,是为了让父进程和OS来进行回收,可用来检测该进程退出的异常性。

演示僵尸状态

【Linux】进程与进程状态_第30张图片

【Linux】进程与进程状态_第31张图片

4.8 孤儿进程

  • 父进程如果提前退出,那么子进程后退出,进入 Z 之后,那该如何处理?
  • 父进程先退出,子进程就称为“孤儿进程”
  • 孤儿进程被 1 号 inti 进程领养,当然要有 inti 进程的回收 

【Linux】进程与进程状态_第32张图片

【Linux】进程与进程状态_第33张图片

【Linux】进程与进程状态_第34张图片

你可能感兴趣的:(Linux,linux,运维,服务器)