学习内容:
1、进程相关知识(用户空间、内核空间、进程创建、进程优先级、进程内存)
2、Linux进程查看及管理工具(ps、pgrep、pidof、kill、jobs、uptime、top、htop、vmstat、pmap、)
一、进程相关知识
操作系统的组成部分:硬件,kernel,lib,
系统调用-->调用kernel
lib调用--> 库调用,kernel调用
运行用户代码-->用户模式-->用户空间;
运行kernel-->内核模式-->内核空间
内核的功用:进程管理、文件系统、网络功能、内存管理、驱动程序、安全功能等
内核空间和用户空间关系:
对计算机来说,其实只有CPU和内存,其中在某一时刻内存逻辑上分为两部分(linux系统):用户空间和
内核空间,每一个用户进程在内存的用户空间进行运行,当用户进程需要进行硬件资源的访问和使用时此时会
通过系统调用到内核空间,因为只有内核才有权限进行硬件的访问,此时未运行完的进程会暂时中止(保留现
场),CPU进而处理内核相关请求,而中止的进程相关状态信息保存在内核task struct(Linux内核存储进程
信息的数据结构格式),即相当于内核会建立一个的运行的。
程序的数据库,当内核硬件的请求CPU处理完毕,内核会根据记录进程数据库中读取进程的状态(恢复现
场),从而知道程序运行到哪一步,进而继续运行下去,而不需要重新运行进程因为每个进程可以通过系统调用
进入内核,因此,Linux内核空间由系统内的所有进程共享。
进程和线程的关系:
进程和线程都是由操作系统所体会的程序运行的基本单元,系统利用该基本单元实现系统对应用的并发性。
进程和线程的区别在于: 简而言之,一个程序至少有一个进程,一个进程至少有一个线程. 线程的划分尺度小于
进程,使得多线程程序的并发性高。
另外,进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率。
线程在执行过程中与进程还是有区别的。每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出
口。但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。
从逻辑角度来看,多线程的意义在于一个应用程序中,有多个执行部分可以同时执行。但操作系统并没有将
多个线程看做多个独立的应用,来实现进程的调度和管理以及资源分配。这就是进程和线程的重要区别。
进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的
一个独立单位.
线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程自己
基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属
一个进程的其他的线程共享进程所拥有的全部资源.
一个线程可以创建和撤销另一个线程;同一个进程中的多个线程之间可以并发执行.
进程的创建:
init(centos6)
systemd(centos7)是无法像内核调用特权指令,但是可以进行创建进程;
进程是由父进程创建:父子关系
fork(请求创建进程的调用接口;)
clone(克隆自己的数据给子进程;)
任何进程销毁都是其父进程进行销毁;
fork(), clone()
进程优先级:
0-139:
0-99:实时优先级;-->数字越大优先级越高;
100-139:静态优先级;-->数字越小优先级越高;
NICE值:
-20,19程序的优雅值:
1、普通用户只能调大自己进程的nice值
2、root可以调大调小nice
时间复杂度:Big O,用时和规模的关系(横坐标可以是规模或者队列数列,纵坐标是时间)
Big O
O(1),O(logn),O(n)线性,O(n^2)抛物线,O(2^n);
每个程序有2个队列:运行队列,过期队列;
程序运行优先级查看运行队列:
进程的task struct:
进程内存:
内核完成资源分配:
同一个命令,不同数据使用的内存也是不一样的;
将内存分割成一个个4k的页框存储页面数据;
page frame:页框,存储页面数据;
每个进程的所占的内存有page frame组成;伪装成连续空间给进程;
以32位系统位列:每个进程运行时内核告诉进程有3G内存可用;-->虚拟内存-->线性地址空间;
真正分配的内存空间:物理地址空间:-->与先行地址空间是离散对应的;
内存为每个进程都保存了task stauct;
MMU:Memory Management Unit内存管理单元;
缺页异常:访问数据,发现物理空间数据不在了;
常驻内存集:不能被交换
虚拟内存集:可以进行交换-->swap上
进程间通讯 IPC:Inter Process Communication
进程与进程无法通信:
如需要通信:同一主机上;
signal :发信号的形式实现
shm:shared memory 共享内存空间;
semerphor:信号量,一种计数器,相当于加上一种标识位,添加访问权限
不同主机上:
rpc:remote procecure call:远程过程调用;
socket:基于套接通信,IP和端口号
Linux内核:抢占式多任务:
进程类型:
守护进程:daemon;与终端无关,在系统引导过程中启动的进程;
前台进程:用户终端启动进程:与终端相关;
注意:也可把在前台启动进程送往后台,变为以守护模式运行;
进程状态:
运行态:running
就绪态或睡眠态:ready
睡眠态:
可中断睡眠:任意时间都可唤醒:interruptable
不可中断睡眠:uninterruptable
进程:指令+数据
一次IO是由分2段进行:磁盘加载内核内存,内核内存复制进程内存;
第二段:IO调用过程。
第一段:
停止态:暂停于内存中,但不会被调度,除非手动启动;
僵死态:zombie
init(systemd):是负责收拾没有父进程的子进程;
二、Linux进程查看及管理工具:
CPU-Bound:CPU密集进程-->消耗更多的CPU
非交互式:
IO-Bound:IO密集进程-->
交互式:
Linux系统状态的查看及管理工具:pstree, ps, pidof, pgrep, top, htop, glance, pmap,
vmstat, dstat, kill, pkill, job, bg, fg, nohup
pstree命令:以树状的方式显示进程
pstree-display a tree of processes
-p 显示进程编号
例: 以树状可以很清晰看见进程跟进程之间的关系
进程管理工具
ps:process state进程状态查看工具:
ps - report a snapshot of the current processes
语法:ps [options]
注意:该命令查看的是某一时刻的瞬间进程运行的状态,非连续查看(静态)
支持三种选项:
UNIX选项如-A -e
BSD选项如a
GUN选项如--help
常用组合:aux
默认显示当前终端中的进程
a 选项包括所有终端中的进程
x 选项包括不链接终端的进程
u 选项显示进程所有者的信息
f 选项显示进程的父进程
o 属性… 选项显示定制的信息::
pid、comm、%cpu、%mem、state、tty、euser、ruser
USER:发起进程的用户
PID:PID号
%CPU:使用CPU百分比
%MEM:使用内存百分比
VSZ:Virtual memory SiZe,虚拟内存集,线性内存,许诺使用内存,
RSS:ReSidentSize, 常驻内存集,实际使用内存
TTY:和终端相关
STAT:进程状态
D:不可中断睡眠
S:可中断的睡眠
R:就绪或运行状态
T:中止状态
Z:僵死状态
<:高优先级进程
N:低优先级进程
+:前台进程组中的进程
l:多线程的进程
s:会话进程的首进程
START:进程开始时间
TIME:进程真正在CPU运行的时间,而非挂表时长
COMMANDD:发起进程的命令,【如果命令中有中括号,代表是内核进程】
常用组合:-ef
-e: 显示所有进程
-f: 显示完整格式程序信息
常用组合:-eFH
-F: 显示更完整格式的进程信息
-H: 以进程层级格式显示进程相关信息
常用组合:自定义
ps -eo pid,tid,class,rtprio,ni,pri,psr,pcpu,stat,comm
ps axo stat,euid,ruid,tty,tpgid,sess,pgrp,ppid,pid,pcpu,comm
ps -eopid,tt,user,fname,tmout,f,wcha
进程优先级分类
ni: nice 值,普通优先级,值越低优先级越高
pri: priority 优先级,进程优先级,数值越大优先级越高
psr: processor CPU编号
rtprio: 实时优先级
搜索进程
最灵活:ps 选项 | 其它命令
按预定义的模式:pgrep
pgrep [options] pattern
-u uid: effective user,生效者
-U uid: real user,真正发起运行命令者
-t terminal: 与指定终端相关的进程
-l: 显示进程名
-a: 显示完整格式的进程名
-P pid: 显示指定进程的子进程
按确切的程序名称:/sbin/pidof
pidof bash
搜索指定进程的pidof init
kill
kill:向进程发送控制信号,以实现对进程管理
显示当前系统可用信号:kill -l trap -l
-l:列出当前kill能够使用的信号(注意是小写L)
常用信号:man 7 signal
1) SIGHUP: 无须关闭进程而让其重读配置文件
2) SIGINT: 中止正在运行的进程;相当于Ctrl+c
9) SIGKILL: 杀死正在运行的进程(强制立刻杀死进程)
15) SIGTERM:终止正在运行的进程(可能不会立即生效,会等进程保存完所有数据才正常退出)
18) SIGCONT:
19) SIGSTOP:
由键盘输入ctrl-c同样的动作-9:立刻强制删除一个作业-15:以正常方式终止一项作业。与-9不一样。
指定信号的方法:
(1) 信号的数字标识;1, 2, 9
(2) 信号完整名称;SIGHUP
(3) 信号的简写名称;HUP
jobs 查看后台执行程序
将“当前”作业放到后台“暂停”:ctrl+z
观察当前后台作业状态:jobs
参数:
-l 列出进程 ID 及其它信息。
-p 仅列出进程 ID。
-n仅列出自从上次输出了状态变化提示(比如显示有进程退出)后的发生了状态变化的进程。
-r 仅显示运行中的作业。
-s 仅显示停止的作业。
-x 运行命令及其参数,并用新的命令的进程 ID 替代所匹配的原有作业的进程组 ID。
将后台作业拿到前台处理:fg
fg %jobnumber (%可有可无)
让作业在后台运行:bg
ctrl+z让当前作业到后台去暂停,bg 作业号就可以在后台run
&是指在后台运行
同时运行多个进程,提高效率
方法1
vi all.sh
f1.sh&
f2.sh&
f3.sh&
方法2
(f1.sh&);(f2.sh&);(f3.sh&)
方法3
{ f1.sh& f2.sh& f3.sh& }
nohup是永久执行
运行 nohup --help
Run COMMAND, ignoring hangup signals. 可以看到是“运行命令,忽略挂起信号”
就是指,用nohup运行命令可以使命令永久的执行下去,和用户终端没有关系,例如我们断开SSH连接都不会
&是指在后台运行,但当用户推出(挂起)的时候,命令自动也跟着退出
那么,我们可以巧妙的吧他们结合起来用就是
nohup COMMAND &
这样就能使命令永久的在后台执行
举个例子nohup tail -f nohup.out
然后退出登录,再连接,用ps -ef 你会还能看到在运行
ps -ef
root 3457 1 0 18:20 ? 00:00:00 tail -f nohup.out
另外,nohup执行后,会产生日子文件,把命令的执行中的消息保存到这个文件中,一般在当前目录下,如果当
前目录不可写,那么自动保存到执行这个命令的用户的home目录下,例如root的话就保存在/root/下
这个我们常在运行命令和脚本中常用到的
系统工具
uptime命令
显示当前时间,系统已启动的时间、当前上线人数,系统平均负载
系统平均负载:(1、5、10分钟的平均负载,一般不会超过1)
指在特定时间间隔内运行队列中的平均进程数。
如果每个CPU内核的当前活动进程数不大于3的话,那么系统的性能良好。如果每个CPU内核的任务数大于5,那
么这台机器的性能有严重问题。
如果linux主机是1个双核CPU的话,当Load Average 为6的时候说明机器已经被充分使用了。
进程管理工具
top命令:
选项:
-d #: 指定刷新时间间隔,默认为3秒
-b: 以批次方式
-n #: 显示多少批次
有许多内置命令:
排序:
P:以占据的CPU百分比,%CPU
M:占据内存百分比,%MEM
T:累积占据CPU时长,TIME+
首部信息显示:
uptime信息:l命令
tasks及cpu信息:t命令
cpu分别显示:1 (数字)
memory信息:m命令
退出命令:q
修改刷新时间间隔:s
终止指定进程:k
保存文件:W
栏位信息简介
us:用户空间
sy:内核空间
ni:调整nice时间
id:空闲
wa:等待IO时间
hi:硬中断
si:软中断(模式切换)
st:虚拟机偷走的时间
栏位信息简介
PID (Process Id):任务的进程ID
PPID (Parent Process Pid):父任务的进程ID
RUSER (Real User Name):任务的所有者真实名称
UID (User Id):任务所有者ID
USER (User Name):任务所有者名称
GROUP (Group Name):任务所有者群组名
TTY (Controlling Tty):终端
PR (Priority):优先级
%CPU (CPU usage):CPU使用率
%MEM (Memory usage (RES)):内存使用率
S (Process Status):进程状态
TIME+ (CPU Time, hundredths):CPU时间,精确到秒
htop命令:需从Fedora-EPEL源安装
选项:
-d #: 指定延迟时间;
-u UserName: 仅显示指定用户的进程;
-s COLUME: 以指定字段进行排序;
子命令:
s: 跟踪选定进程的系统调用;
l: 显示选定进程打开的文件列表;
a:将选定的进程绑定至某指定CPU核心;
t: 显示进程树
F1-F10选项
F3直接搜索进程
F9发送kill命令,默认级别是15
vmstat命令:查看虚拟内存信息
vmstat [options] [delay [count]]
-s 内存信息汇总
procs:
r:等待运行的进程的个数,和核心数有关
b:处于不可中断睡眠态的进程个数(被阻塞的队列的长度)
memory:
swpd: 交换内存的使用总量
free:空闲物理内存总量
buffer:用于buffer的内存总量
cache:用于cache的内存总量
swap:
si:从磁盘交换进内存的数据速率(kb/s)
so:从内存交换至磁盘的数据速率(kb/s)
io:
bi:从块设备读入数据到系统的速率(kb/s)
bo: 保存数据至块设备的速率
system:
in: interrupts, 中断速率,包括时钟
cs: context switch, 进程切换速率
cpu:
us: Time spent running non-kernel code
sy: Time spent running kernel code
id: Time spent idle. Linux 2.5.41前,包括IO-wait time.
wa: Time spent waiting for IO. 2.5.41前,包括in idle.
st: Time stolen from a virtual machine. 2.6.11前, unknown.
例1:vmstat 2 5 两秒一次,显示5次
例2:查看内存汇总信息
例3:dd if=/dev/sda of=/dev/null 测试硬盘读数据,并且监控
可以看见io bi暴增,假如系统的io值过高,这个时候就需要查看是系统哪个进程占用大量的io了
例4:dd if=/dev/zero of=f1 测试硬盘写数据,并且监控
可以看见io bo暴增,假如系统的io值过高,这个时候就需要查看是系统哪个进程占用大量的io了
注意:例3和例4都是测试磁盘吞吐量
如果io比较大,可以看看是哪个程序产生那么大的io,磁盘io太大的话会带来系统的负载偏大
pmap命令:进程的内存映射
pmap[options] pid[...]
-x: 显示详细格式的信息;
cat /proc/PID/maps
另外一种实现: pmap1
资源监视工具 Glances
图中颜色含义为:
绿色:OK(正常)、蓝色:CAREFUL(注意)、紫色:WARNING(警告)、红色:CRITICAL(严重),状态
阀值可参考或修改/etc/glances/glances.conf
默认刷新时间间隔为3s,可通过 glances -t xx指定刷新时间
退出可按q、Esc、Ctrl-C
监控界面可用选项:
命令
说明
a 自动排序
l Show/hide logs
c 根据CPU使用率排序
b Bytes or bits for network I/O
m 根据内存占用比排序
w 删除警告日志
p 根据进程名字排序
x 删除警告和严重级别的日
i Sort processes by I/O rate
1全局CPU或者每个CPU的状态
d 显示/隐藏硬盘I/O状态
h Show/hide this help screen
f 显示/隐藏文件系统状态
t View network I/O as combination
n 显示/隐藏network状态
u View cumulative network I/O
s 显示/隐藏sensors状态
q Quit (Esc and Ctrl-C also work)
y 显示/隐藏hddtemp状态
glances支持远程模式:
即可以以C/S模式工作:
Server: 以监听模式启动glances;
Client: 以远程模式启动glances,远程连入指定服务器,并显示Server上的相关性能数据;
服务模式:
glances -s -B 本地IP地址
-B: 用于指明监听的本地地址;
客户端模式:
glances -c 服务器IP地址
-c: 用于连入的服务器的地址;
在172.18.70.70上执行glances -s -B 172.18.70.70
在172.18.70.40上执行glances -c 172.18.70.70
注意:可能由于防火墙的原因无法连接
glances 的高级应用
glances 的结果输出方法
让 glances 输出 HTML 格式文件,首先安装相关软件包
[root@centos7 ~] # yum install Jinja2
[root@centos7 ~] # glances -o HTML -f /var/www/html
[root@centos7 ~]#systemctl start httpd