linux进程管理与作业控制简述
一、进程的相关概念和理论
1、进程是运行中的程序实例。进程与程序是有区别的,程序是静态的指令和数据集合,而进程是动态的使用系统资源的程序,一个程序可启动多个进程。每个用户任务,每个系统管理的守护进程都可称之为进程。linux根据进程的优先级为每个进程分配合适的时间片,轮流调度到CPU上运行,从而实现“多任务”
2、为利于软件开发标准的统一,内核给每个进程编造一个数据结构(task_struct),虚拟出大小相同的地址空间,进程直接运行于各自的虚拟地址空间而非物理内存中,彼此独立。在32位系统中,这个虚拟地址空间最大为4G,linux分配1G给内核(内核空间),剩下3G给进程(用户空间)。每个进程都以为自己独占3G空间,实际只映射到物理内存的一小部分;每个进程也都以为只有自己与内核交互,实际上内核被映射到所有进程的内核空间。
3、linux进程有两种执行状态:用户态和内核态。用户态是进程的普通执行状态,一个进程在运行过程中,总是在两种执行状态之间不断地转换
进程虚拟地址空间分为:用户空间和内核空间。
①进程一般运行于用户空间,用户空间中存放着用户进程本身的程序和数据
②内核被映射到所有进程的内核空间;进程运行在用户态下时,不允许直接访问内核空间;进程只能通过系统调用转换为内核态后,才能访问内核空间。
③用户进程访问硬件(例如对硬盘的读写操作)是需要进行系统调用的,由内核获取结果后再反馈给进程
虚拟地址空间和物理地址空间都使用分页机制,虚拟地址空间中叫页面,物理内存中叫页框,页面和页框大小必须相同。CPU借助MMU(Memory Management Unit,内存管理单元)处理虚拟地址到物理地址的映射。
4、进程上下文:系统提供给进程处于动态变化的运行环境总和。
5、进程的分类:
实时进程:是一直运行的进程,经常随系统启动而启动,在系统关闭时终止。它们独立于终端,并且周期性的执行某种任务或等待处理某些事件。实时进程的优先级高于普通进程
普通进程
6、按对资源占用的偏重又可将进程分为:CPU密集型和I/O密集型
7、进程优先级
CPU根据进程优先级来挑选进程,进程优先级的范围为0~139
实时优先级:0~99,数字越大,优先级越高
静态优先级:100~139,数字越小,优先级越高
用户可通过调整nice值来改变进程优先级:PRI(new)=PRI(old)+NI(nice值)。nice值的范围为-20~19,用户空间的进程启动时,优先级默认为120,nice值默认为0。普通用户只能调大nice值,即只能调低优先级,root不受限制。
动态优先级:由内核维护,动态调整
8、进程状态
运行态:running
睡眠态:sleeping
可中断睡眠:interruptable
不可中断睡眠:等待外部满足之前无法继续运行, uninterruptable
停止态:不会被内核调度并运行
僵死态:zombie。进程已终止, 但task_struct还在, 等待父进程回收
9、进程创建机制
每一个进程都是由其父进程fork()自身而来。fork是一个系统调用,当一个进程调用fork的时候,实际是把父进程的task_struct(任务结构体)拷贝出一个构建一个新的进程,然后为子进程创建新的附加信息。每个子进程在运行结束后都由其父进程来销毁。若父进程先于子进程停止,则子进程会变成“僵尸”进程,一直停留在内存中而无法回收。
10、进程间的通信机制
同一主机:
信号(signal)
共享内存(share memory)
管道(pipe)
旗语(semerphor)
不同主机:
rpc:remote procedure calling
socket
11、CPU的虚拟化:就是将CPU的运行切割为时间片,分给各个进程
12、线程:是比进程更小的可以被单独调度的单位,实际上是把进程的执行流分成多条得到的。
我们把进程看作处理某个任务的车间,这个车间有很多工人,他们协同完成这个任务,线程就好比车间里的工人,一个进程可包括多个线程。车间的空间为工人们共享,象征着进程的内存空间为其包含的每个线程所共享。
同一个进程中的多个线程之间可以并发执行;一个线程可以创建和撤销另一个线程.
因为共享内存,线程之间有可能产生资源争用,一个解决办法就是当线程占用某个资源时,给其“加锁”
进程有独立的内存单元,一个进程崩溃并不会影响另一个进程。而线程没有单独的地址空间,一个线程死掉等于整个进程死掉,因此线程并不利于资源的管理与保护,但线程很轻量级,切换迅速且开销小。
二、linux进程状态查看工具
1、pstree:显示进程树
用法:pstree [option]
常用选项:
-p:显示进程号
-a:显示每个程序的完整指令,包含路径,参数或是常驻服务的标示
-u:显示进程由哪个用户启动
- [root@localhost ~]# pstree
- init─┬─NetworkManager
- ├─abrtd
- ├─acpid
- ├─atd
- ├─auditd───{auditd}
- ├─automount───4*[{automount}]
- ├─certmonger
- ├─cupsd
- ├─dbus-daemon
- ├─hald─┬─hald-runner─┬─hald-addon-acpi
- │ │ └─hald-addon-inpu
- │ └─{hald}
- ├─6*[mingetty]
- ├─modem-manager
- ├─rpc.statd
- ├─rpcbind
- ├─rsyslogd───3*[{rsyslogd}]
- ├─sshd───sshd───bash───pstree
- ├─udevd
- └─wpa_supplicant
2、ps:用于报告当前系统的进程状态(快照式,非动态)。可以搭配kill命令随时中断、删除不必要的程序
用法:ps [option]
ps命令支持三种选项使用风格:
SysV风格:选项可以组合在一起,并且选项前必须有“-”连字符
BSD风格:选项可以组合在一起,但是选项前不能有“-”连字符
GNU风格的长选项,选项前有“--”字符
常用选项:
BSD风格:
a:显示所有与终端相关的进程
x:显示所有进程
u:以用户为主的格式显示进程信息
常用组合:aux
SysV风格:
-e:显示所有进程,相当于-A
-f:显示完整格式的信息
-F:显示额外信息
-H:显示进程的树状结构
-u USERNAME|UID:显示指定用户的所有进程
常用组合:-ef,-eFH
o,-o:自定义要显示的信息,例如ps axo pid,command,psr,pri,ni
显示的字段的含义:
VSZ:virtual memory size,占用的虚拟内存大小
RSS:Resident Set Size,常驻内存集。即占用的物理内存大小,不包括那些被交换出去的内存
STAT:状态
R: running
S: 可中断睡眠
D:不可中断睡眠
T:stopped
Z:zombie
s: session leader
+:前台进程
l: 多线程进程
N:低优先级进程
<: 高优先级进程 COMMAND:若被包含在括号中则表示为内核线程 PSR:表示进程运行于哪颗CPU核心上 3、pgrep:从运行进程队列中查找进程 用法:grep [option] [程序名] 常用选项: -u USERNAME|UID:仅显示由指定用户启动的进程 -g GROUPNAME|GID:仅显示与指定组相关的进程 -t 终端:仅显示与指定终端相关的进程 -l:同时显示进程号和程序名 例如 pgrep httpd ptrep -l -t pts/0
- [root@localhost ~]# pgrep -l ssh
- 4149 sshd
- 6926 sshd
- 6977 sshd
- [root@localhost ~]# pgrep -l -u apache
- 6532 httpd
- 6533 httpd
- 6534 httpd
- 6535 httpd
- 6536 httpd
- 6537 httpd
- 6538 httpd
- 6539 httpd
4、pidof:显示指定程序所启动的进程的ID
用法:pidof 程序名
[root@localhost ~]# pidof httpd
6539 6538 6537 6536 6535 6534 6533 6532 6530
5、top:实时动态地显示系统运行情况,包括进程ID、内存占用率、CPU占用率等
用法:top [option]
常用选项:
-d:屏幕刷新间隔时间
-u:指定用户名
-b:以批次的方式显示top刷新
-n:显示的批次
在top命令提供的界面中可使用一些交互命令:
h:显示帮助页面,给出一些简短的命令说明
q:退出
m:切换显示内存信息
t:切换显示进程和CPU状态信息
s:设置刷新时间间隔
l:显示或隐藏uptime、load average等信息
f:增加或减少进程显示标志
i:只显示正在运行的进程
k:终止指定进程
S:累计模式,会把已完成或退出的子进程占用的CPU时间累计到父进程的TIME+
M:按%MEM进行排序
P:按%CPU排序(默认)
T:按TIME+排序
几个特殊字段的含义:
PRI:进程优先级
NI:nice值
VIRT:进程占用的虚拟内存
RES:进程的常驻内存大小
SHR:共享内存大小
TIME+:进程启动后占用的CPU时间总计
如下图:
第一行:03:52:07表示当前时间;up 1 day, 7:45表示系统开机到现在运行的时长;load average: 0.00, 0.00, 0.00 #表示过去1分钟、5分钟、15分钟的CPU负载信息
第三行:Cpu(s)中的s表示有多个CPU核心,可按数字1将分别显示各CPU核心的信息;
us:用户进程占用CPU时间百分比;
sy:内核占用CPU时间百分比;
id:空闲CPU时间百分比;
wa:等待I/O的CPU时间百分比;
hi:CPU硬中断时间百分比;
si:CPU软中断时间百分比;
st:被偷走的CPU时间百分比,例如虚拟化
- [root@localhost ~]# top
- top - 03:52:07 up 1 day, 7:45, 2 users, load average: 0.00, 0.00, 0.00
- Tasks: 107 total, 1 running, 106 sleeping, 0 stopped, 0 zombie
- Cpu(s): 0.0%us, 0.2%sy, 0.0%ni, 99.7%id, 0.0%wa, 0.0%hi, 0.2%si, 0.0%st
- Mem: 1012352k total, 801028k used, 211324k free, 58128k buffers
- Swap: 2097144k total, 336k used, 2096808k free, 603168k cached
- PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
- 7062 root 20 0 15032 1296 996 R 0.3 0.1 0:00.79 top
- 1 root 20 0 19364 1356 1136 S 0.0 0.1 0:01.29 init
- 2 root 20 0 0 0 0 S 0.0 0.0 0:00.03 kthreadd
- 3 root RT 0 0 0 0 S 0.0 0.0 0:01.73 migration/0
- 4 root 20 0 0 0 0 S 0.0 0.0 0:02.54 ksoftirqd/0
- 5 root RT 0 0 0 0 S 0.0 0.0 0:00.00 migration/0
- 6 root RT 0 0 0 0 S 0.0 0.0 0:01.07 watchdog/0
- ...
6、htop:一款交互式的进程查看工具,比top更强大。来自epel源,需额外安装
在htop命令提供的界面中可使用一些交互命令:
u: 交互式选择显示指定用户的进程
l: 显示光标所在进程所打开的文件列表
s: 显示光标所在进程执行的系统调用
a: 绑定进程到指定的CPU
#:快速定位光标至PID为#的进程上
F1/h:查看帮助
F2/S:设置
F3或/:搜索进程
F4或\:过滤器,按关键字搜索
F5/t:显示树形结构
F6:选择排序方式
F7或[:减小nice值,即提高对应进程的优先级
F8或]:增大nice值,即降低对应进程的优先级
F9/k:杀掉选中的进程
F10/q:退出
M:按MRM%排序
P:按CPU%排序
T:按TIME+排序
7、vmstat:显示虚拟内存状态,但它也可以报告关于进程、内存、I/O等系统整体运行状态
常用选项:
-s:显示内存统计数据
-a:显示活跃和非活跃内存
几个字段的含义:
procs:
r:running,运行队列的长度。太长说明CPU性能不够
b:blocking,被阻塞(等待I/O完成)队列的长度。太长说明磁盘性能不够好
memory:
swpd:已使用的swap大小
free:空闲的物理内存大小
buff:用作缓冲的内存大小
cache:用作缓存的内存大小;cache与buffer的区别见文末补充部分
swap
si:Amount of memory swapped in from disk,每秒从交换区写入内存的大小
so:Amount of memory swapped to disk,每秒写入交换区的内存大小
io:
bi:每秒读取的块数
bo:每秒写入的块数
system:
in:interrupt,每秒中断数,包括时钟中断
cs:context switch,每秒上下文切换数
- [root@localhost ~]# vmstat
- procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----
- r b swpd free buff cache si so bi bo in cs us sy id wa st
- 0 0 336 183768 58676 631048 0 0 4 15 10 8 0 0 100 0 0
- [root@localhost ~]# vmstat -s
- 1012352 total memory
- 828816 used memory
- 323136 active memory
- 382408 inactive memory
- 183536 free memory
- 58716 buffer memory
- 631080 swap cache
- 2097144 total swap
- 336 used swap
- 2096808 free swap
- ...
8、uptime:查看系统运行时长、系统负载等。实际是就是top命令显示的第一行信息
9、dstat:一个用来替换vmstat、iostat、netstat、nfsstat和ifstat这些命令的工具,是一个全能系统信息统计工具,拥有彩色的界面,支持即时刷新,例如输入dstat 3即每秒刷新一次
用法:dstat [option]
常用选项:
-c:显示CPU统计数据
-d:显示disk统计数据
-D DISK: 只显示指定disk的统计数据
-g:显示page的统计数据
-i:显示中断的统计数据
-m:显示内存的统计数据
-l:显示系统负载的统计数据
-n:显示网络情况
-N INTERFACE: 仅显示指定的网络接口的数据
-s:显示交换内存
-p:统计进程信息
--ipc:显示ipc消息队列、信号量和共享内存的使用状况
-y:系统状态数据
-f:以完整格式显示所有信息
--top-cpu:查看当前占用CPU最高的进程
--top-mem:查看当前消耗内存最高的进程
网络连接状态统计:
--tcp
--udp
--raw
--unix
直接使用dstat,则相当于使用“dstat -cdngy”,也相当于“dstat -a”
使用"dstat -v",显示结果类似于vmstat命令
10、pmap:显示指定内存的物理内存空间映射表,实际上是读取/proc/#/maps
用法:pmap [-x|-d] PID
-x:显示扩展格式
-d:显示设备格式
- [root@localhost ~]# pidof httpd
- 8785 8784 8783 8782 8781 8780 8779 8778 8776
- [root@localhost ~]# pmap -x 8785
- 8785: /usr/sbin/httpd
- Address Kbytes RSS Dirty Mode Mapping
- 00007f2a39749000 8 0 0 r-x-- apr_ldap-1.so
- 00007f2a3974b000 2044 0 0 ----- apr_ldap-1.so
- 00007f2a3994a000 4 4 4 rw--- apr_ldap-1.so
- 00007f2a3994b000 48 16 0 r-x-- libnss_files-2.12.so
- 00007f2a39957000 2048 0 0 ----- libnss_files-2.12.so
- 00007f2a39b57000 4 4 4 r---- libnss_files-2.12.so
- 00007f2a39b58000 4 4 4 rw--- libnss_files-2.12.so
■上面我们提到,内核为每个进程维持一个task_struck(任务结构),为便于管理,linux将这些进程的task_struck也抽象成文件的形式置于/proc目录下,并以各进程的PID命名。而上述的各种进程信息查看工具,实际上就是读取这些文件的信息。
三、调整linux进程优先级
前面提到,可通过修改nice值(-20~19)来调整静态优先级;用户空间的进程启动时,优先级默认为120,nice值默认为0。普通用户只能调大nice值,即只能调低优先级,root不受限制。调整进程优先级的命令有nice和renice
1、启动一个进程时直接指定其nice值。
nice -n # COMMAND
例 nice -n 5 mysql
2、调整已运行的进程的nice值:
renice -n # [[-p] pid...] [[-g] pgrp...] [[-u] 用户名...]
-g pgrp:修改所有属于指定进程组的进程的优先级
-u 用户名:修改所有隶属于指定用户的进程的优先级
例 renice -n 3 -p
- [root@localhost ~]# nice -n 5 top
- [root@localhost ~]# ps axo command,ni | grep 'top'
- top 5
- grep top 0
- [root@localhost ~]# pidof httpd
- 8302 8301 8300 8299 8298 8297 8296 8295 8293
- [root@localhost ~]# ps axo command,pid,pri,ni | grep '8302'
- /usr/sbin/httpd 8302 19 0
- grep 8302 8370 19 0
- [root@localhost ~]# renice -n 3 -p 8302
- 8302: old priority 0, new priority 3
- [root@localhost ~]# ps axo command,pid,pri,ni | grep '8302'
- /usr/sbin/httpd 8302 16 3
- grep 8302 8373 19 0
四、使用kill命令向指定进程发信号
前面提到过,同一主机的进程间可通过发信号的方式通信。
kill:发送指定的信号到相应的进程
①kill -l:列出全部信号名称
②几个常用信号:
1) SIGHUP:让程序重读配置文件而无需重新启动
2) SIGINT:interrupt,打断正在运行中的程序
9) SIGKILL:杀死进程
15) SIGTERM:终止进程
③每个信号都可以使用三种方式之一在Kill进行调用:
数字代号: 如1, 2, 9, 15
信号完整名称:如SIGHUP, SIGINT, SIGKILL, SIGTERM
信号简称:如HUP, INT, KILL, TERM
④kill [-SIGNAL] PID:向指定进程发送指定信号。若不指定信号,默认为SIGTERM
⑤killall [-SIGNAL] COMMAND,其效果等同于kill [-SIGNAL] `pidof COMMAND`
- [root@localhost ~]# kill -l
- 1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP
- 6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1
- 11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM
- 16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
- 21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
- 26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR
- 31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3
- 38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8
- 43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
- 48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
- 53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7
- 58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2
- 63) SIGRTMAX-1 64) SIGRTMAX
- [root@localhost ~]# top &
- [2] 8437
- [root@localhost ~]# kill -9 8437
- [2]+ Stopped top
- [root@localhost ~]# pidof httpd
- 8466 8465 8464 8463 8462 8461 8460 8459 8457
- [root@localhost ~]# killall httpd
- [root@localhost ~]# pgrep httpd
五、linux作业控制
1、作业分类:
前台作业:通过终端启动,并在终止之前一直占据着终端。手动启动的非守护进程类的程序,一般都运行于前台
后台作业:作业启动之后即运行于后台,释放前台;
2、如何将作业运行于后台:
①运行中的作业:ctrl+z;送往后台后,作业处于STOPPED状态
②尚未启动作业:COMMAND &
3、一般情况下,若退出终端,则与终端相关的作业会被终止;如果想把作业送往后台,且与终端无关:
nohup COMMAND &
4、作业都有作业号,使用jobs命令查看
5、作业控制命令:
fg [[%]JOBNUM]: 将指定的作业调回前台。或不指定作业号,默认为带+号的作业
bg [[%]JOBNUM]: 让送往后台的作业在后台继续运行;某些命令无法在后台继续运行
kill %JOBNUM: 终止指定的作业;注意:kill作业时要带%号
- [root@localhost ~]# vim a.txt
- [1]+ Stopped vim a.txt
- [root@localhost ~]# top &
- [2] 8574
- [root@localhost ~]# ping www.baidu.com
- PING www.a.shifen.com (115.239.211.112) 56(84) bytes of data.
- 64 bytes from 115.239.211.112: icmp_seq=1 ttl=128 time=5.54 ms
- 64 bytes from 115.239.211.112: icmp_seq=2 ttl=128 time=6.91 ms
- ^Z
- [3]+ Stopped ping www.baidu.com
- [root@localhost ~]# jobs
- [1] Stopped vim a.txt
- [2]- Stopped top
- [3]+ Stopped ping
- [root@localhost ~]# fg
- ping www.baidu.com
- 64 bytes from 115.239.211.112: icmp_seq=4 ttl=128 time=9.70 ms
- 64 bytes from 115.239.211.112: icmp_seq=5 ttl=128 time=10.2 ms
- ^C
- --- www.a.shifen.com ping statistics ---
- 12 packets transmitted, 12 received, 0% packet loss, time 35180ms
- rtt min/avg/max/mdev = 3.931/6.099/10.299/1.886 ms
- [root@localhost ~]# fg 1
- vim a.txt
- [root@localhost ~]# jobs
- [2]+ Stopped top
- [root@localhost ~]# kill %2
- [root@localhost ~]# jobs
补充:cache与buffer的区别
简而言之,cache一般与读操作相关,而buffer一般与写操作相关
首先从翻译上看,cache翻译为“缓存”,而buffer翻译为“缓冲”
①从硬件层面看,cache为cpu集成的高速缓存,而buffer应该为一段内存
cache是为了提高读取速度,把经常或马上需要读取的数据预读到缓存中,写进cache的数据是为了其它设备从中去读取,如cpu
buffer是为了让不同速度的设备能够同步而建立的一个缓冲区域,写进buffer的数据是为了从中拿出写入其它设备
②从软件这一层来说,cache是文件系统的缓存,buffer是块设备的缓冲
cache以页面形式缓存了文件系统的文件,给需要使用的程序读取,避免频繁读硬盘,提高读取效率
buffer以块形式缓冲了对块设备的操作,定时或手动地同步到硬盘,它是为了缓冲写操作然后一次性将很多改动写入硬盘,避免频繁写入,提高写入效率。