Linux系统中的基本运行单位是进程,通过对系统系统中的进程的管理能够对系统的实时运行状态进行了解和调度。Linux中提供了用于查看、调整和停止进程的命令。本文仍然以RHEL6说明Linux系统的进程管理。

一、进程概述

程序是保存在存储介质中的可执行机器代码(或指令)和数据的集合,而进程是在计算机处理器执行中的计算机程序。

他们的关系如下: 程序是保存在外部存储介质中的可执行代码和数据,是静态保存的代码。 进程是程序代码在处理器中的运行,是运行中的程序的一个副本,是被载入内存的一个指令集合。

进程ID(Process ID,PID)号码被用来标记各个进程 进程又可以有属性,比如UID、 GID、和SELinux语境决定对文件系统的存取和访问权限,这些属性通常从执行进程的用户来继承 进行程存在生命周期,从启动,执行再到结束,都可以各种时长的生命周期。

在进程的生存期内将使用许多系统资源,它将使用CPU来运行指令,使用物理内存来保存执行代码和数据,它将打开和使用文件子系统中的文件,并直接或间接地使用系统中的物理设备。

Task struct:Linux内核存储进程信息的数据结构格式 Task list:多个任务的的task struct组成的链表

第一个进程:

Centos 6系统 init

Centos 7系统 systemd

像父子关系,也像树状一般 进程:都由其父进程创建

进程的5种基本状态与转换

 创建状态:进程在创建时需要申请一个空白PCB(processcontrol block进程控制块),向其中填写控制和管理进程的信息,完成资源分配。如果创建工作无法完成,比如资源无法满足,就无法被调度运行,把此时进程所处状态称为创建状态

 就绪状态:进程已经准备好,已分配到所需资源,只要分配到CPU就能够立即运行

 执行状态:进程处于就绪状态被调度后,进程进入执行状态

 阻塞状态:正在执行的进程由于某些事件(I/O请求,申请缓存区失败)而暂时无法运行,进程受到阻塞。在满足请求时进入就绪状态等待系统调用

 终止状态:进程结束,或出现错误,或被系统终止,进入终止状态。无法再执行

 时间片
时间片即CPU分配给各个程序的时间,每个线程被分配一个时间段,称作它的时间片,即该进程允许运行的时间,使各个程序从表面上看是同时进行的。如果在时间片结束时进程还在运行,则CPU将被剥夺并分配给另一个进程。如果进程在时间片结束前阻塞或结束,则CPU立即进行切换。而不会造成CPU资源浪费。在宏观上:我们可以同时打开多个应用程序,每个程序并行不悖,同时运行。但在微观上:由于只有一个CPU,一次只能处理程序要求的一部分,如何处理公平,一种方法就是引入时间片,每个程序轮流执行。
我们将CPU就类比为电话亭,每一个进程都是一个需要打电话的人。现在一共有4个电话亭(就好比我们的机器有4核),有10个人需要打电话。现在使用电话的规则是管理员会按照顺序给每一个人轮流分配1分钟的使用电话时间,如果使用者在1分钟内使用完毕,那么可以立刻将电话使用权返还给管理员,如果到了1分钟电话使用者还没有使用完毕,那么需要重新排队,等待再次分配使用。

状态之间转换六种情况
 运行——>就绪:
1,主要是进程占用CPU的时间过长,而系统分配给该进程占用CPU的时间是有限的;
2,在采用抢先式优先级调度算法的系统中,当有更高优先级的进程要运行时,该
进程就被迫让出CPU,该进程便由执行状态转变为就绪状态。
 就绪——>运行:运行的进程的时间片用完,调度就转到就绪队列中选择合适的进程分配CPU
 运行——>阻塞:正在执行的进程因发生某等待事件而无法执行,则进程由执行状态变为阻塞状态,如发生了I/O请求
 阻塞——>就绪:进程所等待的事件已经发生,就进入就绪队列

以下两种状态是不可能发生的:
 阻塞——>运行:即使给阻塞进程分配CPU,也无法执行,操作系统在进行调度时不会从阻塞队列进行挑选,而是从就绪队列中选取
 就绪——>阻塞:就绪态根本就没有执行,谈不上进入阻塞态

进程优先级:
系统优先级:0-99(CentOS6)
实时(realtime)优先级: 99-0
nice优先级:-20到19

进程内存:
Page Frame: 页框,用存储页面数据,存储Page 4k
LRU:Least Recently Used 近期最少使用算法,释放内存物理地址空间和线性地址空间
MMU:Memory Management Unit负责转换线性和物理地址
TLB:Translation Lookaside Buffer 翻译后备缓冲器,用于保存虚拟地址和物理地址映射关系的缓存

在计算机网络体系中,主机与主机之间的通讯,实质上是 主机进程与主机进程之间的通讯,也就是进程间的通讯(IPC: Inter Process Communication)。
当两个进程在同一主机时,就可以依靠 signal(信号指令)、shm(shared memory共享内存空间)、semaphore(信号量,一种计数器)来完成。
当两个进程不在同一主机时,进程间通讯可以依靠socket(套接字 IP和端口号)、RPC: remote procedure call、MQ:消息队列来完成。

进程状态:
Linux内核:抢占式多任务
 进程类型:
守护进程daemon 在系统引导过程中启动的进程,和终端无关进程
前台进程 跟终端相关,通过终端启动的进程
注意:两者可相互转化

 进程状态:
运行态 running
就绪态 ready
睡眠态 可中断:interruptable
不可中断:uninterruptable
停止态 stopped 暂停于内存,但不会被调度,除非手动启动
僵死态 zombie 结束进程,父进程结束前,子进程不关闭
 进程的分类:
CPU-Bound:CPU密集型,对CPU占用率高的进程。非交互
IO-Bound:IO密集型,等待I/O时间长的进程,交互。

进程管理:
如果Linux系统整个系统资源快要被耗尽时,我们是否能够找出最耗费资源的那个进程,然后结束该进程,让系统恢复正常呢?或者某个程序存在BUG,导致产生一系列的问题,又如何查找到它并结束进程呢?又譬如同时有多个应用程序在运行,但其中某个非常重要,该如何让这个最重要的进程先运行呢?
碰到这些情况,都应该先查询下系统当前所运行的进程,此时就可以通过一些进程管理工具来获得。
Linux系统各进程的相关信息均保存在 /proc/PID 目录下的各文件中。
如当前进程:#pstree -p|grep `echo $$`
|-sshd(1185)---sshd(1288)---bash(1292)-+-grep(4421)
一个进程可以有多个线程,一个线程对应一个进程。

进程优先级调整:
静态优先级:100-139
进程默认启动时的nice值为0,优先级为120,只有根用户才能降低nice值(提高优先性)
 nice命令: 用于程序执行前指定具体优先级
nice [-n] [OPTION] [COMMAND [ARG]...]
#nice -n -5 ping -f 127.0.0.1
#ps -C ping o pid,cmd,ni,%cpu,psr
PID CMD NI %CPU PSR
3545 ping -f 127.0.0.1 -5 116 1


 renice命令:用于程序执行后指定具体优先级
renice [-n] 优先级数值 进程号

#renice -n -20 3380
3380 (process ID) old priority 0, new priority -20

常用进程管理工具
指令 描述
ps 显示当前时间点进程的运行情况
pstree 以树状图的方式展现进程之间的派生关系
pidof 查找一个运行的程序的PID
pgrep 以名称为依据从运行进程队列中查找进程,并显示查找到的进程id
top 性能分析工具,能够实时显示系统中各个进程的资源占用状况
htop 跟top类似,但是比top更强大,可支持鼠标操作。需要EPEL源。
glance 查看 CPU、负载、内存、磁盘 I/O、网络流量、文件系统、系统温度等信息.EPEL源
pmap 显示一个或多个进程的内存状态
vmstat 可以展现给定时间间隔的服务器的状态值,包括服务器的CPU使用率,
内存使用,虚拟内存交换情况,IO读写情况等
dstat 动态显示系统资源统计,代替vmstat,iostat
iotop 监视磁盘I/O使用状况的top类工具。iotop具有与top相似的UI,
其中包括PID、用户、I/O、进程等相关信息。
kill 用来删除执行中的程序或工作。kill可将指定的信息送至程序
pkill 按照进程名杀死进程
job 显示Linux中的任务列表及任务状态,包括后台运行的任务。
该命令可以显示任务号及其对应的进程号
bg 用于将作业放到后台运行,该命令的运行效果与在指令后面添加符号&的效果是相同的
nohup 将程序以忽略挂起信号的方式运行起来,被运行的程序的输出信息将不会显示到终端
pstree
功能描述: display a tree of processes
格式:
默认:

版本 选项 说明 示例
-p 显示出进程号和线程
-s 显示指定进程父子关系,centos 6不支持
-H PID 高亮显示指定进程
#pstree -p
大括号代表是线程

显示其他用户的进程
#pstree -p hunk
bash(10665)───vim(10692)

显示指定进程
#pstree -ps 755
systemd(1)───NetworkManager(755)─┬─dhclient(910)
├─dhclient(914)
├─dhclient(5180)
├─{NetworkManager}(765)
└─{NetworkManager}(773)