推荐链接:
进程管理常用命令
进程简介:
何为进程?
简单讲,进程(process)是运行中的程序的一个副本;从创建开始,到下一次结束终止是它的生命周期;
惯例上图先,
进程的调度
执行用户代码的机制叫用户空(即用户模式);
执行内核的代码的机制叫内核空间(即内核模式)
如果发生系统调用,就会转换成内核模式,然后又会切换到用户模式;这种叫做模式切换
内核功用:进程管理、文件系统、网络功能、内存管理、驱动程序、安全功能;
cpu上的指令:
CPU环0,特权指令,只有kernel才能运行
CPU环3上的指令普通用户能运行
内核功用:进程管理、文件系统、网络功能、内存管理、驱动程序、安全功能;
执行用户代码的机制叫用户空(即用户模式);
执行内核的代码的机制叫内核空间(即内核模式);
整个代码的执行过程中,可能需要不断的在自己能执行的代码和调用内核所执行的代码间转换;如果代没有权限执行时,就要做模式转换,也就意味程序要发起一次软中断,软中断的作用就是要发起系统调用的,执行内核中的代码;
如果需要做管理类操作时,就会发起系统调用。任何需要系统特权指令的功能,操作系统就把它封装成一个一个的调用;任何人任何程序都不得直接操作,必须向内核调用才可以;
模式切换:理想状态70%用户 30%内核
多任务是各进程之间是以时间片切割,一个进程运行的时间到了就下去让其他需要的上来。
多个进程都在等待的话就需要优先级;内核负责进程调度的,它会会将霸占的时间的进程踢掉,
进程的当前状态在CPU上,CPU上有指令指针寄存器,寄存器保存了当前进程的状态,其运行速度接近CPU的速度;等要切换下一个进程时;内核在完成进程切换时找一个位置保存进程执行的中间状态,这叫做保存现场;恢复第二个进程现场,进程间切换不断发生保存切换现场;
进程的管理
Linux 内核存储进程信息的固定格式:task struct;多个任务的task struct组件的链表:task list ;为了追踪内存中的结构信息,内存有了链表(双向链表,双向循环链表)
如果内存空间中存储了一段进程的相关信息,为了找寻一下个与之相同的结构体信息,每一个进程结构体结束的地方都有一小段数据,这些数据指向用来存放同样数据的内存的地址;这样就会形成一个链表;
参考:
linux内核调度算法(2)--CPU时间片如何分配
http://blog.csdn.net/russell_tao/article/details/7103012
Android系统开发(8)——linx进程基本概念
http://www.bkjia.com/Androidjc/871896.html
进程调度的基本概念
http://oa.gdut.edu.cn/jpkc/os/multimedia/oscai/chapter2/pages/ch28.htm
Linux内核剖析之进程地址空间(一)
http://www.2cto.com/os/201408/322865.html
linux 进程地址空间的一步步探究
http://blog.chinaunix.net/uid-26833883-id-3193585.html
task_struct结构描述
http://blog.csdn.net/allen_young_yang/article/details/6101015
进程的创建
init进程负责创建所有的进程;进程都由其父进程创建,内核开设的调用并由fork生成子进程,父进程克隆clone()自己的数据给子进程;创建子进程的目的是在某一时刻来帮父进程完成某一任务。这里需要提及下写时复制;
coW写实复制:
我们知道进程间的内存地址空间是隔离的,fork()系统调用的结果是生成一个新的子进程,为了保证隔离性, 早期的UNIX采用在fork()将父进程的地址空间完整的复制一份。这个操作非常的耗时。 为了提高效率现代的Unix及Linux采用了一种称为写时复制的技术,其实也就是一种延迟操作的做法, 子进程和父进程在fork()时并不马上复制,而是暂时共享内存空间,随后只要父进程或者子进程试图写共享的内存就会产生一个异常, 这时内核才把内存空间进程复制,比如我们在Shell中启动一个程序时随后就会启动新的程序,启动后的程序将会覆盖旧的内存空间, 如果提前就复制了,那么这个复制操作其实是白做了,为此系统将这个操作优化为写时复制;
参考:
Linux写时拷贝技术(copy-on-write) :http://www.cnblogs.com/biyeymyhjob/archive/2012/07/20/2601655.html
父子进程关的系也是保存在task struct中,
父进程---->静默--处理销毁子进程--->
| |
| |
子进程---->>
为了能够实现快速进程调用,我们用140个队列保存装载进程,相同优先级的为一个队列,调用时内核只需要扫描队列的首部,根据优先级来判断哪个先执行;每一个队列都有两队:运行队列,过期队列,这样就280个队列了,程序从运行队列中运行完毕,就会被抛到过期队列;等运行队列被运行完了,就会和过期队列调换位置;
进程优先级:
0-139:
1-99:实时优先级
数字越大优先级越高
100-139:静态优先级
数字越小优先级越高
Nice值:-20-19,对应静态优先级
-20对应100
19对应139
普通用户只能调低自己的优先级,只有管理员才能调高;
Big O:复杂度,呈现什么样的走势
O(1):无论复杂度多大,解决的时间都是恒定的;理想标准;
Temp=i;i=j;j=temp;
以上三条单个语句的频度均为1,该程序段的执行时间是一个与问题规模n无关的常数。算法的时间复杂度为常数阶,记作T(n)=O(1)。如果算法的执行时 间不随着问题规模n的增加而增长,即使算法中有上千条语句,其执行时间也不过是一个较大的常数。此类算法的时间复杂度是O(1)。
O(logn):对数
O(n): 线性,次线性
O(n**2): 平方
O(2**n): 指数,有时叫作“几何”(阶)
参考:
大O符号
http://baike.baidu.com/link?url=OpMWVJjZ4h6ZV79Yz2wHXTg1a_vm7Ywi0dKjZH-3Cr7H1Y964sAG4Rq51Z-4xDkWPBrKMyWhHTbrB0uwR4xjC_
算法的时间复杂度(大O表示法)
http://xushixiong.vip.blog.163.com/blog/static/81094067200811184214426/
log(logarithms)
http://baike.baidu.com/link?url=A11fWl0T_lX7K5jbVPYjLTLgOZKXQwZv8tMk9taP0fxaIpwfNja_uWDDCIHoSBBpDYCjb1rG05aeZV39Vka0rpvp9nhMAoKABOPhwNPkdkq
进程内存:
简单理解:内核把内存划分成固定大小的内存空间,一般4k,把这些集中分配给进程,伪装成一个连续的内存;
Page Frame :页框,用存储页面数据
LRU算法:当内存不够用时,就会将内存中最近最少使用的进程放进交换分区中;
MMU:内存管理单元Memory Management Unit
MMU的作用:当一个进程被加载至CPU上运行时,将其映射关系放到MMU芯片上,负责完成实时转换;当一个进程的指令访问它的某个地址(虚拟地址)空间的数据时,就会转换为真正的物理地址并找到真正的数据(task struct);
参考:
硬件篇之MMU: http://my.oschina.net/jerikc/blog/228869
缺页异常:
如果此前把一个数据交换出来或者放到其他位置去了,那么它此时的映射关系就被破坏了,所以必须要重新映射;对于整个系统来讲,一个进程访问某空间以为要找的数据在自己的进程空间中,一旦访问了却没有,那么这个数据就必须从磁盘载入;从磁盘载入有两种可能:1、此前没有载入,所以要从文件读进来;2、数据放在交换内存中,也需要载入,这就会造成缺页异常;访问数据发现数据不在就是缺页;
进程中有些数据必须在内存中,有些可以被换出的;必须在内存中的就叫做常驻内存集,而能交换出去的就是交虚拟内存集;
IPC进程间通信机制
虽然进程以为只有自己在运行,但必要时还是需要进程间通信的,这时就需要IPC机制;
IPC:Inter Process Communication进程间通信
同一个主机上:
signal #发现号
shm:share memory #共享内存
semnphor #打手势
不同主机上:
rpc:remote procecure call远程过程调用
socket:#套接字通信
Linux内核:抢占式多任务
任何一个进程,当它需要启动时,发现别的进程在运行,可把别的进程的CPU运行时间抢占过来;比如每个进程运行时间为5毫秒,这5毫秒分配可以抢占的时间点,如果没人抢这五毫秒就走完了;
进程类型:
守护进程:daemon,在系统引导过程启动的进程,跟终端无关的进程;
前台进程:跟终端相关,通过终端启动的进程
注意:也可以在前台的进程 送往后台,以守护模式运行;
进程状态:
运行状态:running
就绪态:ready;什么都具备,就是没调度CPU;可以运行,但没有被运行;也可以称为睡眠态;
睡眠态:可中断、不可中断
可中断:interruptable;可以立即被调度到CPU运行;
不可中断:uniterruptable;调度到CPU运行不起来;进程运行过程中需要加载数据,而内存中没有时就请求内核操作,内核将数据先加载到内核内存中再从内核内存复制到进程内存中,期间这样的一次I/O等待,进程是运行不起来的;
一次IO分两步:
1 内核将数据加载到内核内存中
2 从内核内存中复制到进程内存
停止态:暂停于内存中,但不会被调度,除非手动启动之;stopped
僵死态:zombie,任何进程都由父进程帮助收尸的,父进程挂了,子进程就变成了僵尸
进程的分类:
CPU-Bound:CPU密集型,消耗CPU资源多
IO-Bound:I/O密集型,一般交互的进程I/O比较多
Linux系统上的进程查看及管理工具
pstree,ps,pidof,pgrep,top,htop,glances,pmap,vmstat,dstat,kill,pkill,job,bg,fg,nohup,nice,renice,killall,...
pstree命令:
进程树查看,倒置的树
演示:
CentOS7 :systemd
[root@localhost ~]# pstree
systemd─┬─NetworkManager─┬─dhclient
│ └─3*[{NetworkManager}]
├─2*[abrt-watch-log]
├─abrtd
├─agetty
├─alsactl
├─atd
├─auditd─┬─audispd─┬─sedispatch
│ │ └─{audispd}
│ └─{auditd}
├─chronyd
├─crond
├─dbus-daemon───{dbus-daemon}
├─irqbalance
├─lsmd
├─lvmetad
├─master─┬─pickup
│ └─qmgr
├─polkitd───5*[{polkitd}]
├─rsyslogd───2*[{rsyslogd}]
├─smartd
├─sshd───sshd───bash───pstree
├─systemd-journal
├─systemd-logind
├─systemd-udevd
└─tuned───4*[{tuned}]
CentOS 6 :init
[root@centos6 ~]# pstree
init─┬─NetworkManager─┬─dhclient
│ └─{NetworkManager}
├─abrtd
├─acpid
├─atd
├─auditd───{auditd}
├─automount───4*[{automount}]
├─console-kit-dae───63*[{console-kit-da}]
├─crond
├─cupsd
├─dbus-daemon
├─hald─┬─hald-runner─┬─hald-addon-acpi
│ │ └─hald-addon-inpu
│ └─{hald}
├─irqbalance
├─login───bash
├─5*[mingetty]
├─modem-manager
├─rpc.statd
├─rpcbind
├─rsyslogd───3*[{rsyslogd}]
├─sshd───sshd───bash───pstree
├─udevd───2*[udevd]
└─wpa_supplicant
ps 命令:
ps - report a snapshot of the current processes.
显示命令执行这一刻瞬间的状态,并不动态连续;通过查看/proc/PID下查看,当前进程状态;如果想对进程运行时间监控,应该用 top 工具
内核中的状态信息供过/proc/输出给用户;内核参数有2类,其参数被模拟成文件系统类型:
- 可设置其值从而调整内核运行特性的参数;/proc/sys/
- 状态变量:其用于输出内核中统计信息或状态信息,仅用于查看
ps [options]:
选项有三种风格:
1 UNIX
2 BSD
3 GNU
启动进程的方式:
系统启动过程中自动启动:与终端无关的进程;
用户通过终端启动:与终端相关的进程;
选项:
a:所有与终端相关的进程;
x: 所有与终端无关的进程;
带[]标识内核线程;
u: 以用户为中心来组织进程状态信息显示;
-e:显示所有进程
-f: 显示完整格式的进程信息
-F: 显示完整格式的进程信息
C:CPU utilization
PSR: 运行在哪个CPU之上
-H:以层级结构显示进程的相关信息;
常用组合之一:aux
VSZ:虚拟内存集
RSS:Resldent Size,常驻内存集
STAT: 运行状态
R:running
S:interruptable sleeping 可中断睡眠
D:uninerruptable sleeping 不可中断睡眠(通常 IO 的进程)
T:Stopped 停止态
Z:zombie 僵死态
+:前台进程
l: 多线程进程
N:低优先级进程
<:高优先级进程
s: session leader 会话领导者
常用组合之二:-ef
C:CPU占用百分比
STIME:启动时间
TIME:累计运行时间
常用组合之三:-eFH
常用组合之四:-eo,axo
o field1,field2,...: 自定义要显示的字段列表,以逗号分隔;
常用的field:pid,ni,pri,psr,user,pcpu,pmem,stat,comm,tty,ppid,rtprio
ni:nice值;
pri:priorty ,优先级;
rtprio:real time priority,实时优先级;
psr:运转那个cpu上
pcpu:cpu利用率
pmem:内存占用率
user:进程用户
args:显示命令和参数
comm:程序名
stat:状态
tty:终端
ppip:父进程号
演示:
[root@centos7 1]# ps aux | head -2 #BSD风格
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.6 44000 6524 ? Ss 09:55 0:03 /usr/lib/systemd/systemd --switched-root --system --deserialize 24
VSZ:虚拟内存集 ;RSS:Resldent Size,常驻内存集 ;STAT: 运行状态
[root@centos7 1]# ps -ef | head -2 #UNIX风格
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 09:55 ? 00:00:03 /usr/lib/systemd/systemd --switched-root --system --deserialize 24
[root@centos7 1]# ps -eo ni,pid,pcpu,psr,comm,user,pmem | head -2
NI PID %CPU PSR COMMAND USER %MEM
0 1 0.0 1 systemd root 0.6
pgrep,pkill命令:
- look up or signal processes based on name and other attributes
pgrep [options] pattern 根据进程相关属性查找进程
pkill [options] pattern 发送信号(signal)到指定进程
[options]
-u uid: effective user显示指定用户的进程
-U uid:read user
-t TERMINAL:与指定的终端相关的进程;
-l:显示进程名
-a: 显示完整格式的进程名;
-P pid: 显示此进程的子进程
pidof命令:
根据进程名去其PID;
top命令:显示进程相关信息
排序:
P:cpu百分比排序,默认
M:以占据内存百分比排序;
T:累计占用CPU时间排序
改变排序列:shift + > 或 shift + <,默认cpu
高亮显示当前运行进程:b
高亮显示列:x
显示 完整命令:c
首部信息:
1、utptime信息: l命令启动关闭
2、3:task及cpu信息:t命令启动关闭
4、5:内存信息:m命令启动关闭
退出:q
修改刷新时间间隔;s
终止指定的进程:k
选项:
-d # : 指定刷新的时间间隔,默认3秒
-b: 以批次方式显示;
-n # 显示多少批次;
uptime命令:显示系统时间、运行时长及平均负载;
过去1分钟、5分钟和15分钟的平均负载;
等待运行的进程队列的长度;
演示:
[root@centos7 ~]# top -n 1
top - 16:12:59 up 6:17, 3 users, load average: 0.08, 0.03, 0.05
Tasks: 363 total, 1 running, 362 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.0 us, 0.1 sy, 0.0 ni, 99.8 id, 0.1 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 1003192 total, 721120 free, 127032 used, 155040 buff/cache
KiB Swap: 2097148 total, 2097148 free, 0 used. 720936 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
137 root 20 0 0 0 0 S 5.9 0.0 0:03.74 rcu_sched
1行、utptime信息: l命令启动关闭
16:12:59: 当前时间
up 6:17: 运行时长
3 users: 当前用户登录数
load average: 0.08, 0.03, 0.05:平系统负载
平系统负载: 过去1分钟、5分钟、15分钟平均队列长度,等待CPU运行的进程队列长度;
注意:通常平均负载长时间超过3个,代表cpu应付不了当前业务负载需要;通常队列长度的总数量不能大于CPU的数量;
2,3行:task及cpu信息:t命令启动关闭
Tasks:
363 total: 进程总数
1 running: 正在运行的进程数
362 sleeping:睡眠的进程数
0 stopped: 停止的进程数
0 zombie: 僵尸进程数
%Cpu(s):
0.0 us:用户空间占用CPU百分比
0.1 sy:内核空间占用CPU百分比
0.0 ni:用户进程空间内改变过优先级的进程占用CPU百分比
99.8 id:空闲CPU百分比
0.1 wa:等待I/O完成的CPU时间百分比
0.0 hi:硬中断
0.0 si:软中断
0.0 st:被虚拟化程序偷走的时间百分比;运行虚拟机软件,那些时间被虚拟机拿走了;
注意:正常us与sy比率在7:3左右;wa很大,代表I/O系统成为性能瓶颈;st判断当前cpu实时负载;
4,5行:内存信息:m命令启动关闭
KiB Mem :
1003192 total: 物理内存总量;1G
721120 free: 空闲内存总量:
127032 used: 使用的物理内存总量
155040 buff/cache:用于缓存缓冲的内存空间;不算是真占用,可被回收;
注意:真正空闲内存空间 = free + buff/cache
KiB Swap:
2097148 total: 交换区总量
2097148 free: 空闲交换区总量
0 used: 使用的交换区总量
720936 avail Mem:
进程信息:
PID: 进程id
USER: 进程所有者的用户名
PR: 优先级;100+NICE值
NI: nice值。负值表示高优先级,正值表示低优先级
VIRT: 虚拟内存集
RES: 常驻内级
SHR: 共享内存空间
S: 进程状态
D=不可中断的睡眠状态
R=运行
S=睡眠
T=跟踪/停止
Z=僵尸进程
%CPU: 上次更新到现在的CPU时间占用百分比
%MEM: 进程使用的物理内存百分比
TIME+ :进程使用的CPU时间总计,单位1/100秒
COMMAND:启动命令
htop命令:
选项:
-d #: 指定延迟时间间隔;
-u UserName: 仅显示指定用户的进程;
-s COLUME:以指定字段进行排序;
子命令:
l: 显示选定的进程打开的文件列表;
s:跟踪选定的进程的系统调用;
t:以层级关系显示各进程状态;
a: 将选定的进程绑定至某指定的CPU核心;
vmstat命令:
- Report virtual memory statistics报告虚拟内存的统计数据
vmstat [options] [delay [count]]
~]# vmstat 2 3 每2秒钟显示一次,共3次
选项:
-s:显示内存统计数据
procs:
r:running;等待运行的进程个数;CPU上等待运行的任务队列长度;实时的值;
b:处于不可中断睡眠态的进程个数;被阻塞的任务队列的长度;
注意:
a队列长期大于系统CPU的个数,说明CPU不足,需要增加CPU;
b队列太长,代表等待I/O很大,I/O能力不佳;
memory:
swpd:交换内存使用总量;
free:空闲的物理内存总量;
buffer:用于buffer的内存总量;缓冲
cache:用于cache内存总量;缓存
注意:
swpd值很大时,代表当前物理内存太少,对于服务器来讲能不使用交换内存最好;
swap:
si:数据进入swap中的数据速率(kb/s)
so:数据离开swap中的数据速率(kb/s)
注意:
si,so很大时,物理内存不够用;如果si很大,换出so很少时,表示目前目前不是很严重;
io:
bi:从块设备读入数据到系统的速率(kb/s)
bo:保存数据至块设备的速率(kb/s)
注意:
bi,bo很大时,只能说读写很大,并不能判断性能问题;
system:
in:interrupts,中断速率;
cs:context switch,上下文切换的速率
注意:
cs一旦达到上万个,说明需要运行的进程太多,cpu性能需要提高;
cpu
us: user space
sy:system
id:idle
wa:wait
st: stolen
pmap命令:
- report memory map of a process
pmap [options] pid [...]
-x :显示详细格式的信息;
另一种查看
cat /proc/PID/maps
glances命令:类似于top,htop
- A cross-platform curses-based monitoring tool
需要配置好epel源安装,由于监控系统可以实现远程数据采集,这里就不过多叙述;
内建命令:
a Sort processes automatically l Show/hide logs
c Sort processes by CPU% b Bytes or bits for network I/O
m Sort processes by MEM% w Delete warning logs
p Sort processes by name x Delete warning and critical logs
i Sort processes by I/O rate 1 Global CPU or per-CPU stats
d Show/hide disk I/O stats h Show/hide this help screen
f Show/hide file system stats t View network I/O as combination
n Show/hide network stats u View cumulative network I/O
s Show/hide sensors stats q Quit (Esc and Ctrl-C also work)
y Show/hide hddtemp stats
常用选项:
-b:以Byte为单位显示网上数据速率;
-d:关闭磁盘I/O模块;
-m:关闭mount模块;
-n:关闭network模块;
-t #:刷新时间间隔;
-1:每个cpu的相关数据单独显示;
-o {HTML|CSV}:输出格式;
-f /PATH/TO/SOMEDIR:设定输出文件的位置;
C/S模式下运行glances命令:
服务模式:
glances -s -B IPADDR
IPADDR:本机的某地址,用于监听;
客户端模式:
glances -c IPADDR
IPADDR:是远程服务器的地址;
dstat命令:
- versatile tool for generating system resource statistics
资源系统统计数据的工具,基于python集合vmstat\top\iostat\ss等多种命令
dstat [-afv] [options..] [delay [count]]
常用选项:
-c, --cpu:显示cpu相关信息;
-C #,#,...,total
-d, --disk:显示磁盘的相关信息
-D sda,sdb,...,tobal
-l: 显示负载
-g:显示page相关的速率数据;
-m:Memory的相关统计数据
-n:Interface的相关统计数据;
-p:显示process的相关统计数据;
-r:显示io请求的相关的统计数据;
-s:显示swapped的相关统计数据;
--tcp:显示tcp连接状态
--udp:显示udp连接状态信息
--raw:raw套接字状态信息
--socket: 套接字状态信息
--ipc:ipc状态信息
--top-cpu:显示最占用CPU的进程;
--top-cpu-adv:(incl. pid and other stats)
--top-io:最占用io的进程;
--top-io-adv:(incl. pid and other stats)
--top-mem:最占用内存的进程;
--top-lantency:延迟最大的进程;
kill命令
- terminate a process用于向进程发送信号,以实现对进程的管理;
显示当前系统可用信号:
kill -l [signal]
每个信号的标识方法有三种:
1) 信号的数字标识;
2) 信号的完整名称;
3) 信号的简写名称;
向进程发信号:
kill [-s signal|-SIGNAL] pid...
常用信号:
1) SIGHUP:无须关闭进程而让其重读配置文件;
2)SIGINT:终止正在运行的进程,相当于Ctrl+c
9)SIGKILL:杀死运行中的进程;
15)SIGTERM:终止运行中的进程;
18)SIGCONT:
19)SIGSTOP:
killall命令:
- kill processes by name
kill [-SIGNAL] program
Linux系统作业控制
- 前台作业(foregroud):通过终端启动,且启动后会一直占终端;
- 后台作业(backgroud):可以通过终端启动,但启动后即转入后台运行(释放终端)
如何让作业运行于后台?
(1)运行中的作业
Ctrl+z
注意:送往后台后,作业会转为停止态;
(2)尚未启动的作业
# COMMAND &
注意:此类作业虽然被送往后台,但其依然与终端相关;终端终止,与终端相关的进程也会终止;如果希望把送往后台的作业剥离与终端的关系:
# nohup COMMAND &
查看所有的作业:
# jobs
可实现作业控制的常用命令:
# fg [[%]JOB_NUM] :把指定的作业调回前台;
# bg [[%]JOB_NUM] :让送往后台的作业在后台继续运行;
# kill %JOB_NUM :终止指定的作业;
调整进程优先级
可通过nice值调整的优先级范围:100-139 分别对应于:-20,19
进程启动时,其Nice值默认为0,尤其优先级是120;
nice命令:
以指定的nice值启动并运行命令
nice [OPTION] [COMMANDE [ARGU]...]
选项:
-n NICE
注意:仅管理员可以调低nice值;
renice命令:调整运行中的nice值
# renice [-n] NICE PID...
查看Nice值和优先级: ps axo pid,ni,priority,comm
[root@centos7 ~]# ps axo pid,ni,priority,comm | head -5
PID NI PRI COMMAND
1 0 20 systemd
2 0 20 kthreadd
3 0 20 ksoftirqd/0
5 -20 0 kworker/0:0H