一、进程
进程:init(1)-->系统的第一个进程,通过fork调用其他进程,自身由内核发起。
通过pstree可以查看进程之间的父子关系。
[root@localhost ~]# pstreeinit─┬─NetworkManager─┬─dhclient│ └─{NetworkManager}├─abrtd├─acpid├─atd├─auditd───{auditd}├─crond├─cupsd├─dbus-daemon───{dbus-daemon}├─hald─┬─hald-runner─┬─hald-addon-acpi│ │ └─hald-addon-inpu│ └─{hald}├─master─┬─pickup│ └─qmgr├─6*[mingetty]├─modem-manager├─rsyslogd───3*[{rsyslogd}]├─sshd───sshd───bash───pstree├─tpvmlp├─udevd───2*[udevd]├─vmtoolsd───{vmtoolsd}├─vmware-vmblock-───4*[{vmware-vmblock}]└─wpa_supplicant
1、进程的分类
内存地址空间分配使用情况说明
1
进程间通讯:IPC inter process communication
不同程序调用相同的库文件,就需要进程间通讯。
进程分为两类:
CPU-bound:CPU密集型进程
IO-bound:IO密集型进程
进程按处理时间分:
批处理进程
实时进程
交互式进程
2、进程间工作原理
进程切换
为什么要有进程切换
因为一个系统要提供多个进程同时工作,也就是多任务的概念,那么每个程序可能由多个进程组成,每个进程又分配了优先级和时间片,如果一个进程时间片用完,就要给另一个进程使用了,另一种情况是,一个进程的工作需要调用另一个进程来协助完成,再有就是被抢占。这三种方式都需要进程切换。
如何实现进程切换
进程进行切换前需要有现场保护的一个工作,对方进程完毕切换回来还需要一个现场恢复的过程。
进程如果需要切换到其他进程上需要由内核来完成,自己不能直接处理,这个时候就有了系统调用的概念,就是内核帮助进程完成某些工作,cpu的工作模式分为内核模式(ring0)和用户模式(ring3),内核会依据级别来确定是工作在内核模式上还是用户模式上,所以说有系统调用就必然有模式切换。
什么是模式切换?
就是在进行系统调用的时候产生的对cpu工作模式的切换,带内核工作完成后再将工作还给进程。
模式切换不是上下文切换,什么是上下文切换呢?
上下文切换是指一个进程结束,执行另一个进程或者被抢夺的情况,称为上下文切换。
3、IO操作
什么是io(输入输出)
一个系统的运行,是要为人服务的,就是说人可以进行输入操作,并通过输出获得结果,这个就是io操作。
系统如何识别io的操作
io操作有很多,可以是键盘输入,批处理命令,远程操作等等,内核如何识别这些操作,并准确处理呢,
首先如何获取io操作,早期是通过忙等待的方式,就是保留一个资源给io接口,等待它的操作指令,第二种是轮询,定期查看io接口是否有输入操作。第三种是中断,就是当有io操作时发送一个中断信号给内核,要求内核处理,这里就可以知道io操作的优先级还是比较高的。
4、优先级
如何设置进程的运行等级?调度器!
进程优先级:
动态优先级
静态优先级:100-139 数值越小优先级越高
可以通过nice值来手动调整,-20,19。
普通用户只可以调大数字,降低优先级。
用法:nice -n # command
实时优先级:调度实时进程,1-99 数值越大优先级越高
5、进程的状态
ready、running、sleeping、stopped,zombie(僵死状态)
多cpu如何应用?
一个程序要运行,(只)开启一个进程的,通常一个程序是只有一个数据流的(按照程序编写的顺序自上向下执行),并只会占用一个cpu的内核,当有多个cpu同时工作的情况,如何利用cpu的优势呢,通常有两种情况:1、将多个进程分配到多个cpu内核上,每个内核就分配到了一定数量的进程,达到了合理分配资源的目的。2、如果只有一个程序占用大量的资源,要给他分配多个cpu内核如何操作呢,就是需要程序在编写的时候,允许多个数据流同时进行,这样在程序创建进程的时候,就可以在一个进程中创建多个线程,每个线程就是一个数据流。linux对线程的支持并不是很好,表现的最终形式就是轻量级进程,最终体现的还是“进程”哦。
基于线程的访问优势就是它是进程的子集,所有在访问重复资源的时候,不需要重复范围,可以通过其他线程上访问,更加快捷,非常适用于web服务。
二、进程管理
进程管理类的命令:
pstree、ps、top、vmstat、htop
1、pstree:查看进程树
[root@localhost ~]# pstree
init─┬─NetworkManager
├─abrtd
├─acpid
├─atd
├─auditd───{auditd}
├─automount───4*[{automount}]
├─bluetoothd
├─certmonger
├─console-kit-dae───63*[{console-kit-da}]
2、PS详解
ps:显示当前进程状态的命令;静态显示。
[root@localhost ~]# ps -efH
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 May15 ? 00:00:01 /sbin/init
root 575 1 0 May15 ? 00:00:00 /sbin/udevd -d
root 2121 575 0 May15 ? 00:00:00 /sbin/udevd -d
root 2122 575 0 May15 ? 00:00:00 /sbin/udevd -d
root 1535 1 0 May15 ? 00:00:00 auditd
root 1569 1 0 May15 ? 00:00:00 /sbin/rsyslogd -i /var/run/s
rpc 1620 1 0 May15 ? 00:00:00 rpcbind
常用参数:
-a所有和终端相关的进程
-x所有和终端无关的进程,用?来表示和终端无关
-u以用户为中心显示进程
-e:显示所有进程
-f:完整格式列表
ppid:父进程号
-F:显示额外信息
psr:表示运行在那颗cpu上
-H:显示进程间的父子关系
-o:自定义显示格式
进程条目:
stat:
S:可中断睡眠状态,
D:不可中断的睡眠。
R:运行或可运行
T:停止
Z:僵死
s:session leader 一个进程的主要进程
l:多线程进程
+:前台进程
N:低优先级进程
<:高优先级进程
time:运行时长
command:进程发起者,命令
vsz:线性地址空间大小,非实际占用大小
rss:实际占用空间大小
%cpu:进程占用cpu时间比
paid:父进程号码
stime:第一次启动时间
time:运行时长
PSR:表示运行在多cpu的那个cpu内核上
u:以用户为中心显示进程的相关信息
TTY:
控制台:/dev/console
虚拟终端:/dev/tty1-6,
模拟终端:远程连接的终端 /dev/pts/0
串行终端:/dev/ttys
3、pgrep详解
显示指定的进程信息。
-U:username 显示相关用户的进程
-G:groupname 显示组的进程
-l:查看指定程序或进程的进程号
[root@localhost ~]# pgrep -U root
1
2
3
4
5
4、pidof
显示某进程的进程号
[root@localhost ~]# pidof sshd
5449 1878
5、top详解
[root@localhost ~]# top
top - 01:18:07 up 19:56, 2 users, load average: 0.00, 0.00, 0.00
Tasks: 99 total, 1 running, 98 sleeping, 0 stopped, 0 zombie
Cpu(s): 0.0%us, 0.0%sy, 0.0%ni,100.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Mem: 1004768k total, 230948k used, 773820k free, 33972k buffers
Swap: 2031612k total, 0k used, 2031612k free, 69424k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1 root 20 0 19364 1540 1228 S 0.0 0.2 0:01.32 init
2 root 20 0 0 0 0 S 0.0 0.0 0:00.00 kthreadd
3 root RT 0 0 0 0 S 0.0 0.0 0:00.00 migration/0
条目详解
load average:每隔5/10/15分钟的队列长度。一般是一个小数
cpu:us:用户空间程序占用%
sy:内核空间程序占用%,她与us的合理比例是7:3,就是us占70%,sy占30%
ni:调整nice值
id:cpu空闲%
wa:(wait)等待磁盘io完成输入输出工作所占据的时间比例
hi:硬件中断占据的百分比
si:软中断占据的百分比
st:被偷走的时间,虚拟机占用运行的时间
PR:优先级 priority
NI:nice值
virt:虚拟内存级
res:实际内存级
shar:共享内存优先级
s:状态stats
%cpu:自从上次刷新到现在cpu被此进程占用的百分比。
选项和参数:
top是交互式命令,通过输入不同的字母显示不同的信息,实际上就是条目的第一个缩写,比如
M:按内存空间占用大小排序
P:按cpu时间占用大小排序
T:按累计时间排序
k:杀死一个进程,输入后需要制定kill 后面的选项1-15,常用是9 强制杀死。
m、p、l用于是否显示抬头的相关信息。
q:退出
-d #:刷新时间
-b:批次显示
-n #:指定批次显示的次数
6、vmstat
查看服务器cpu使用情况,内存、虚拟内存使用情况和磁盘读写情况。
[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 0 164752 1484028 449036 0 0 0 138 10 18 0 0 100 0 0
[root@localhost ~]# vmstat
procs:
r:运行或等待cpu时间片的进程的个数
b:被阻塞的进程队列的长度
memory:
swpd 虚拟内存(swap)已使用的大小,如果大于0,表示你的机器物理内存不足了,如果不是程序内存泄露的原因,那么你该升级内存了或者把耗内存的任务迁移到其他机器。
free 空闲的物理内存的大小,我的机器内存总共8G,剩余3415M。
buff Linux/Unix系统是用来存储,目录里面有什么内容,权限等的缓存,我本机大概占用300多m
cache cache直接用来记忆我们打开的文件,给文件做缓冲,我本机大概占用300多M(这里是Linux/Unix的聪明之处,把空闲的物理内存的一部分拿来做文件和目录的缓存,是为了提高 程序执行的性能,当程序使用内存时,buffer/cached会很快地被使用。)
si 每秒从磁盘读入(放到swap中的数据量)虚拟内存的大小,如果这个值大于0,表示物理内存不够用或者内存泄露了,要查找耗内存进程解决掉。我的机器内存充裕,一切正常。
so 每秒虚拟内存写入磁盘的大小(从swap中读取的数据量),如果这个值大于0,同上。
bi 块设备(磁盘)每秒接收的块数量,这里的块设备是指系统上所有的磁盘和其他块设备,默认块大小是1024byte,我本机上没什么IO操作,所以一直是0,但是我曾在处理拷贝大量数据(2-3T)的机器上看过可以达到140000/s,磁盘写入速度差不多140M每秒
bo 块设备每秒发送的块数量,例如我们读取文件,bo就要大于0。bi和bo一般都要接近0,不然就是IO过于频繁,需要调整。
in 每秒CPU的中断次数,包括时间中断
cs 每秒上下文切换次数,例如我们调用系统函数,就要进行上下文切换,线程的切换,也要进程上下文切换,这个值要越小越好,太大了,要考虑调低线程或者进程的数目,例如在apache和nginx这种web服务器中,我们一般做性能测试时会进行几千并发甚至几万并发的测试,选择web服务器的进程可以由进程或者线程的峰值一直下调,压测,直到cs到一个比较小的值,这个进程和线程数就是比较合适的值了。系统调用也是,每次调用系统函数,我们的代码就会进入内核空间,导致上下文切换,这个是很耗资源,也要尽量避免频繁调用系统函数。上下文切换次数过多表示你的CPU大部分浪费在上下文切换,导致CPU干正经事的时间少了,CPU没有充分利用,是不可取的。
us 用户进程占用CPU时间的百分比,我曾经在一个做加密解密很频繁的服务器上,可以看到us接近100,r运行队列达到80(机器在做压力测试,性能表现不佳)。
sy 系统进程占用CPU时间的百分比,如果太高,表示系统调用时间长,例如是IO操作频繁。
id 空闲 CPU时间,一般来说,id + us + sy = 100,一般我认为id是空闲CPU使用率,us是用户CPU使用率,sy是系统CPU使用率。
wt cpu等待IO完成的时间。
st:被虚拟化偷走的时间
选项:
vmstat delay count:设置vmstat显示的刷新的时间间隔和显示次数 vmstat 2 2
[root@localhost ~]# vmstat 2 2
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 0 164612 1484036 449036 0 0 0 138 10 18 0 0 100 0 0
0 0 0 164612 1484036 449036 0 0 0 0 71 78 0 0 100 0 0
每个两秒显示一次,一共显示两次。
7、sar (system activity reporter)
用来收集、显示保存系统活动信息及报告。
-u:
-P:指定显示cpu的信息
8、iostat:显示系统性能相关信息,硬盘读写情况。
[root@localhost ~]# iostat
Linux 4.6.0 (localhost.localdomain) 2016年05月18日 _x86_64_(1 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle
0.03 0.00 0.14 0.02 0.00 99.81
Device: tps Blk_read/s Blk_wrtn/s Blk_read Blk_wrtn
sda 1.75 25.03 2.41 592778 57170
dm-0 1.82 24.63 2.41 583402 57152
dm-1 0.01 0.11 0.00 2600 0
9、dstat -c 显示cpu详细 实时显示
[root@localhost ~]# dstat
----total-cpu-usage---- -dsk/total- -net/total- ---paging-- ---system--
usrsysidlwaihiqsiq| read writ| recv send| in out | int csw
0 0 100 0 0 0| 15k 1602B| 0 0 | 0 0 | 103 127
0 0 100 0 0 0| 0 28k|2067B 1234B| 0 0 | 101 97
0 0 100 0 0 0| 0 0 |1612B 452B| 0 0 | 80 79
三、信号
引用信号的方法:通过数字、信号名、简写。
显示信号:kill -l
常用信号:
1:sighup:进程不用终止,而可以重读配置文件。对于在线服务可以使用。
2:sigint:中断正在运行的进程,相当于ctrl+c
9:sigkill:杀死一个进程
15:sigterm:终止进程,容许进程可以完成当前工作。
19:sigstop:停止
18:sig
命令:
1、kill -信号 pid
[root@localhost ~]# kill -9 9761
[root@localhost ~]# kill -sigkill 2119
2、killall -信号 进程名
kill是按照pid进行查找并按照信号要求做相应的处理,而killall是按照进程名进行查找并处理相关进程。
3、killall5 -信号
对所有相关进程有效
4、调整进程nice值
nice -n # command 默认优先级是120
renice # pid 对正在运行的进程调整其nice数值
5、作业控制
前台送往后台可以使用ctrl+z,但属于停止状态,后台调到前台使用fg %作业号码
+:下一次后台要运行的作业
-:是在+作业运行完再运行的作业。
bg %作业号码 :让其在后台运行。
启动时,让作业直接在后台运行:command &
用户退出后继续运行作业:nohup command &
终止作业:
kill %作业号码
如果一个程序会产生多个进程,那么快速杀死多个进程的方法:
1、killall,必须给出完整的进程名。
[root@node3.dtedu.com ~]# killall ha_logd
2、pkill,简单给出进程名就可以,名称可以不完整。
[root@node3.dtedu.com ~]# pkill -9 heartbeat
[root@node3.dtedu.com ~]# /sbin/service: line 66: 2291 Killed env -i PATH="$PATH" TERM="$TERM" "${SERVICEDIR}/${SERVICE}" ${OPTIONS}
[1]+ Exit 137 service heartbeat stop
3、正则表达式杀死多进程。
[root@node3.dtedu.com ~]# kill -9 `pgrep crond`
5.1screen
当我们在运行一个程序需要很长时间的时候,可以使用screen,它的特点是用户退出后程序继续运行,并且可以切换到原来窗口中再次查看运行情况。
这里说一下detach(分离、断开),表示用户离开当前shell窗口,并将其放到后台继续执行。并通过screen -r重新登录(attach,附件、连接物)继续后面的操作。
下面实例终端中的
创建一个新的shell窗口,建议取一个名字,8506是进程号,可以通过kill杀死它。也可以使用简便方法直接在screen后面跟shell命令,比如:screen -r test vi ./gongbing.txt
[root@localhost ~]# screen -ls
There are screens on:
8334.pts-0.localhost(Detached)
8506.gong(Detached)#从shell窗口分离出来了,可以重新登录。
8580.cpfrom56(Attached)#表示此shell窗口并没有被分离出来,使用 screen -d 8506解决。
3 Sockets in /var/run/screen/S-root.
[root@localhost ~]# screen -S cpfrom56创建一个新的shell窗口
[root@localhost ~]# ps -axu |grep 8506
Warning: bad syntax, perhaps a bogus ‘-‘? See /usr/share/doc/procps-3.2.8/FAQ
root 8506 0.0 0.1 118776 1556 ? Ss 16:38 0:00 SCREEN -S gong
查看运行中的screen程序screen-ls
BingGongtekiMacBook-Pro:~ binggong$ screen -ls
There is a screen on:
1396.ttys000.BingGongtekiMacBook-Pro(Detached)
1 Socket in /var/folders/dw/wp5cbg3j121_1lvp89533qlr0000gn/T/.screen.
进入某一个screen程序screen-rid
BingGongtekiMacBook-Pro:~ binggong$ screen -r 1396
[screen is terminating]
一个shell窗口中创建多个窗口可以使用ctrl+a+n的方法,切换窗口使用ctrl+a+p,从当前子shell中分离出来ctrl+a+d。
任务完成,退出操作,exit。
shell窗口屏幕共享给其他用户,其他用户远程登录服务器后通过screen -ls查看想要共享的shell窗口,通过screen -x pid来实现共享同一个shell窗口,方便做演示使用。
screen命令详解:http://www.cnblogs.com/mchina/archive/2013/01/30/2880680.html
原文地址:http://137783.blog.51cto.com/127783/1916974