进程的基本概念:
发展壮大离不开广大客户长期以来的信赖与支持,我们将始终秉承“诚信为本、服务至上”的服务理念,坚持“二合一”的优良服务模式,真诚服务每家企业,认真做好每个细节,不断完善自我,成就企业,实现共赢。行业涉及成都OPP胶袋等,在成都网站建设、营销型网站、WAP手机网站、VI设计、软件开发等项目上具有丰富的设计经验。
进程可以理解成运行中的程序的一个副本。程序通过内核调度运行起来成为一个进程,并由内核负责调度其运行于CPU之上以执行程序中的一部分或全部代码,因此进程是运行中的动态实体。而程序是放在文件系统上的一个文件,只要不删除将永久存在,而进程是有生命周期的,每个进程都有创建、运行、结束这一时间段。同一个程序的代码可以被复制多份并由内核调度成多个进程运行,因此可称为运行中的程序的一个副本。
进程调度:
进程管理中最重要的一部分是进程调度,可理解成对各个进程运行时的各种细节的安排和管理。当文件系统上一个可执行程序文件被触发并通过内核调度运行为一个进程时,进程中的指令、数据以及进程相关的属性信息(例如进程的属主、属组、PID等)被内核加载至内存空间中,而指令需要运行在CPU之上,此时CPU中的寄存器可记录正在运行中的指令的状态,例如正在取指令、执行指令、加工数据、取数据...,其中指令指针寄存器IP用于存放下一条要执行的指令的内存地址。
但是需要CPU运行的有众多进程而不只有一个进程,因此内核将CPU切分为多个时间片,并负责将这多个时间片按照优先级分配给各个进程。当一个进程在某一时间片运行与CPU上时,这个时间片就是该进程允许运行的时间,一旦过了这个时间片,该进程将被中断,这时内核把这个进程的中间状态信息按照固定的格式存储于内存中,重新调度另一个进程运行于CPU之上,接着,CPU中用于存放进程状态相关数据将被下一个进程所覆盖。其中,将进程的相关状态信息存储于内存中这一过程称为保存现场,而Linux内核存储进程状态信息是存储进具有固定格式的结构体的,这个结构体就是task struct,多个任务(进程)的结构体(task struct)组成链表结构(task list),根据组成方式的不同有单向链表结构、双向链表结构、循环链表结构、双向循环列表结构等。打个比方,我们盛酒水需要用坛子,而这个固定结构的容器--坛子,就是结构体,总不能用地板装酒水吧?而这些坛子按照一定的组织排列起来的结构可类比为链表结构。
需要注意的是,当CPU上的某一时间片结束后,内核会调度另一个进程运行于CPU之上,而问题是内核该如何从众多等待运行的进程中挑选出一个进程并使其运行于CPU上呢?为了在调度进程时明确哪个进程优先执行,哪个进程后执行,需要用进程优先级来做判断。进程优先级范围是0-139,分为实时优先级(1-99)和静态优先级(100-139),其中实时优先级与内核执行的系统管理操作有关,用户不可对实时优先级进行调整;而用户可以调整的是静态优先级(可通过nice值进行调整),普通用户只可调低不可调高,只有系统管理员才可随意调整。因此,内核是将进程优先级来作为调度进程次序的依据的,但由此内核首先必须知道各个进程的属性(优先级),因此在每次调度进程执行时总得遍历内存上所有结构体中的信息,这将会消耗掉大量的时间。
Linux的2.6版本内核通过精巧的设计解决了这一问题:将所有进程排成140个队列,每个队列对应一个优先级,每个进程归属至其优先级的队列中。而每次内核调度进程执行时只需扫描这140个队列的首部,并从这些队列中挑选出一个进程出来执行即可。这样一来,无论进程有多少个,内核都是通过扫描140个队列首部来实现快速明确调度哪个进程执行于CPU上,因此调度时间不会随进程数量而改变。内核的这种工作模式基于的算法符合程序界的Big O中的O(1)理想模型,即意味着随着算法复杂度的增加,算法解决问题(这里是进程调度速度问题)的时间不会变化。
但这样一来又有一个问题,当一个进程在一个时间片执行完之后应该如何归队呢?在Linux中,进程按照优先级排出队列,而每个队列内部又分为运行队列和过期队列,实际上内核就是通过扫描各个运行队列首部来做判断的,而进程在CPU执行之后返回过期队列中,而运行队列继续等待内核的调度;一旦运行队列中的进程全部执行完毕(每个进程都在CPU上轮流执行了一遍),这时运行队列将转变为过期队列,而原来的过期队列则转变为运行队列等待内核再次调度,重复上述逻辑。
进程创建:
主机开机后,首先将内核加载至内存中,在CPU上开始运行内核代码。接着由进程开始创建初始化进程init,并将用户空间的管理事务交给init这个进程管理。接着init会创建出子进程,而这些子进程可以分别创建出各自的子进程,因此除了init进程之外,其他的进程都由其父进程创建;init进程可视为内核的代理,负责管理用户空间进程的创建和关闭,并向内核提交相应的请求,但init不能代替内核执行特权指令。
那么,在什么情况下父进程需要创建子进程呢?当一个父进程需要借助于某些程序完成复杂任务时,通常需要调用系统上某个可执行程序文件,将其创建为进程,而创建子进程需要通过fork()这个系统调用接口向内核申请提交要创建的进程,而后再通过clone()接口将自身的数据复制一份给子进程;需要注意的是,此时父进程和子进程在内存中占据相同的空间,而一旦子进程需要修改数据时,父进程会重新开辟一个相同的内存空间给子进程,这是父进程和子进程不在占据同一内存空间,这种机制称为写时复制机制(CoW)。
当子进程完成复杂任务时,其父进程会关闭该子进程,内核将内存收回。
init程序在不同版本的体现: CentOS 5: SysV init,经典版本,缺陷是在系统启动和引导时,它创建各子进程是通过写脚本方式借助于 shell来实现的,因为shell脚本是大量命令的堆砌,每个命令运行时会创建进程,因此每启动一 次就需要创建上千个进程,因此执行速度非常慢。 CentOS 6: upstart,基于dbus方式进行通信,同SysV init是通过运行很多命令创建很多进程来完成的,但 不同的是upstart能够并行启动具有关联性的服务程序,实现多线创建进程,如果CPU有多个时会 快很多,而SysV init仅能以串行方式实现启动程序。 CentOS 7: systemd,以一个程序完成整个系统的启动和引导,而且需要启动的进程总数仅有10个左右,因此 系统启动和引导非常快。CentOS7上启动或关闭服务程序时需要通过systemctl实现,因为这些服 务统一由systemd控制; #不同版本的init程序文件名都为init。
进程内存:
承接上述,当内核运行起来之后,会占据一定的内存空间,例如对于Linux来讲一般是1G。其他进程运行起来之后,内核会将内存按空间分成多片分配给各个进程使用,这里的每个“片”指的是页框(page frame),页框就是用来存储页面数据(内存进程信息)的,一个页框就是4K大小的内存空间块。而将真实的物理内存空间连续地分配给各进程使用明显不合适,因为往往空闲的内存空间是离散分布的,而且各个进程在运行过程中会产生各种中间数据,这也会导致进程占据的内存空间加大。因此,内核将底层的物理内存上的空闲的碎片(页框)收集起来,并为上层运行的进程虚拟出连续的内存空间,这个虚拟的内存地址也称为逻辑地址,让每个进程“以为”其占据的内存空间是连续分布的,这个连续的逻辑地址称为线性地址空间。内核会为每个进程虚拟出一个“假象”,即主机上只运行两个程序:内核和进程自己,并且“以为”线性地址空间中除了1G内存分配给内核使用,其余的内存空间均可由进程自己使用。事实上,进程真正只用到一小部分内存空间,并映射到真实的物理内存上连续或离散的内存空间。逻辑地址和物理地址之间映射关系则存储于task struct。当进程执行时,CPU中有专门用于将逻辑地址转换为物理内存地址的电路,即内存管理单元(MMU, Memory Management Unit),因此需要内核将内存的映射关系加载至MMU中。
当进程被分配好内存后,其指令、数据以及进程相关的属性信息会加载至内存中,在内存低地址的地方存放指令(code),而数据可以由变量等数据结构组织存放于内存中,当然也可以是普通数据;进程还会将一部分空间作为堆(heap)内存和栈(stack)内存;当进程运行的中间数据增加时,或者需要加载磁盘上更多数据至内存时,存放于堆内存和栈内存中的数据量增大,堆内存空间向栈顶的方向扩展,而栈内存空间向堆的方向扩展;一旦两者在扩展时相遇,则说明物理内存空间不足;这时交换空间(swap)就出场了,swap可通过近期最少使用算法(LRU, Least Recently Used)扫描出内存上内存上最近不常用的数据,将其暂存于swap中,而腾挪出来的内存空间可供进程使用。
当然,并非所有内存空间中的数据都可交换至swap中,关键性数据(如程序指令code)就不可交换,但非关键性数据(例如程序中的一些不常用数据data);我们把不能用于交换的内存空间称为常驻内存集,而能够交换的内存空间称为虚拟内存集。不过,如果交换了内存空间,那么线性地址空间中映射的物理内存空间地址也会发生改变,因此当进程需要重新访问被交换至磁盘上的swap或加载磁盘上其他空间的数据至内存时,需要先请求内核调用,内核将磁盘上的数据先加载至内核内存中,再复制一份给进程内存。并且,当进程在CPU上执行时需要更新MMU上的映射关系。
进程间通信:
虽说进程“以为”主机上只运行内核和进程自己,但进程间是可以通过IPC(Inter-Process Communication)技术实现通信的。而进程间通信在同一主机上和不同主机上是各不相同的。
IPC(Inter-Process Communication):
同一主机上:
signal:通过发送信号方式通信; shm:通过共享内存方式通信; semerphor:旗语,通过类似“打手势”方式通信;
不同主机上上:
rpc:remote procecure call,即远程过程调用,进程通过调用远程主机上的库函数或数据加工处理 的结果实现通信;rpc是基于socket实现,但比socket更为抽象的一种通信方式; socket:通过进程监听的方式实现通信,通信双方事先需要建立虚链路(tcp连接);在用户空间表现为 socket文件,双方主机上的socket文件都保存本地主机的IP/Port以及对方主机的IP/Port,一方用户 可通过向socket文件写数据,另一方用户则可通过读取socket文件获取数据;
进程类型:
根据是否与终端相关分类:
守护进程:在系统引导过程中启动的进程,跟终端无关; 前台进程:通过终端启动的进程,跟终端相关; #注意:也可以把在前台启动的进程送往后台,以守护模式运行;
根据进程占用CPU多还是IO多分类:
CPU-bound:一般非交互式进程属于CPU密集型; IO-bound:一般交互式进程属于IO密集型;IO密集型进程的优先级应比CPU密集型进程高; #根据Linux哲学思想之一:程序启动之后应尽量避免与用户交互,可知CPU-bound这一类进程应该多 分配一些CPU资源。
进程状态:
(1)运行态:running; (2)就绪态:ready,可以运行但没在CPU上运行;也可以称为睡眠态; (3)睡眠态:分为可中断睡眠和不可中断睡眠; 可中断睡眠:interruptable,任何时候都可唤醒并运行; 不可中断睡眠:uninterruptable,例如等待IO过程; (4)停止态:stopped,即暂停于内存中,不会别调度,除非手动启动之; (5)僵死态:zombie,子进程运行结束之后需要等待其父进程关闭,但若其父进程意外事先关闭,则 子进程会一直等待下去,此时该子进程即为僵尸进程,或者说处于僵死态; #等待IO过程: 当进程执行时需要用到的数据不在内存中时,需要向内核发起申请(通过系统调用接口,进程无法直接 访问硬件),内核将磁盘上的数据先加载至内核内存中,再将内核内存中加载的数据复制一份给进程内 存;
线程的基本概念:
一般来讲,每个程序运行时只能有一个执行流;而如果程序内部有很多代码需要执行并且这些代码彼此之间实现的功能又比较独立,为了让程序执行速度更快,则可通过并行编程的模式将程序开发成可以互相独立并且能单独执行的执行流,而这个执行流就是线程;线程是进程的子单位。当有多个CPU时,程序启动后创建出多个并行执行的线程(执行流),这些线程可分别运行于不同颗CPU之上。不过,当主机只有一个CPU时,将进程分成多个线程执行反而会降低运行速度,因为内核在切换调度进程(线程)时会消耗很多CPU时间。
关于服务类程序:
对于Linux来讲,基本是通过各个具有简单功能的小程序组合起来完成复杂任务的,因此在Linux上进程都是轻量级的,和线程几乎没差别。虽然现在很多服务类程序都是基于并行编程模式编写的,但当服务器接收到的请求过多时响应速度仍然会非常慢,因此现在编程时可通过精巧的设计,使一个进程能同时响应多个进程。
作为一名Linux运维人员,需要有鉴定当前系统的运行状态、资源的消耗情况、进程启动的数量和模式等,例如当用户网页打开速度慢时,我们需要查看当前系统上运行了哪些进程、是否有我们期望运行的进程、期望运行的这个进程占据了CPU和内存多大百分比、是否要调整进程的优先级、以及是否把CPU和内存资源占满......对于较大型的服务类程序,例如Java编写的程序比较吃内存,常常需要运维人员查看jvm虚拟机运行是否正常、是否要调整其垃圾回收策略、是否其内存资源使用的上限或下限、是否要再启动一个jvm进程来实现并行响应......总之,对于运维人员来讲,具有鉴定当前系统上的运行状态的能力非常重要,因为运维基本都是服务,而服务是通过进程来提供的。
Linux系统上的进程查看及管理工具:pstree, ps, pidof, pgrep, top, htop, glances, pmap, vmstat, dstat, kill, pkill, job, bg, fg, nohup, nice, renice, killall, ...
pstree命令:
display a tree of processes
用于显示进程树。
示例:
在CentOS 6上显示进程树:
[root@osyunwei ~]# pstree init─┬─NetworkManager ├─abrtd ├─acpid ├─atd ├─auditd───{auditd} ├─automount───4*[{automount}] ├─bluetoothd ├─certmonger ├─console-kit-dae───63*[{console-kit-da}] ├─crond ├─cupsd ├─dbus-daemon───{dbus-daemon} ├─dmeventd───2*[{dmeventd}] ├─gpm ├─hald─┬─hald-runner─┬─hald-addon-acpi │ │ ├─hald-addon-inpu │ │ ├─hald-addon-rfki │ │ └─hald-addon-stor │ └─{hald} ├─2*[iscsid] ├─iscsiuio───2*[{iscsiuio}] ├─ksmtuned───sleep ├─login───bash ├─master─┬─pickup │ └─qmgr ├─5*[mingetty] ├─modem-manager ├─pcscd───{pcscd} ├─polkitd ├─portreserve ├─rpc.statd ├─rpcbind ├─rsyslogd───3*[{rsyslogd}] ├─sshd─┬─sshd───bash │ └─sshd───bash───pstree ├─udevd───2*[udevd] └─wpa_supplicant
在CentOS 7上显示进程树:
[root@www ~]# pstree systemd─┬─NetworkManager─┬─dhclient │ └─2*[{NetworkManager}] ├─abrt-watch-log ├─abrtd ├─anacron ├─atd ├─auditd───{auditd} ├─crond ├─dbus-daemon───{dbus-daemon} ├─firewalld───{firewalld} ├─httpd───6*[httpd] ├─irqbalance ├─login───bash ├─lsmd ├─lvmetad ├─master─┬─pickup │ └─qmgr ├─polkitd───5*[{polkitd}] ├─rngd ├─rpcbind ├─rsyslogd───2*[{rsyslogd}] ├─smartd ├─sshd───sshd───bash───pstree ├─systemd-journal ├─systemd-logind ├─systemd-udevd ├─tuned───4*[{tuned}] └─vmtoolsd───{vmtoolsd}
ps命令:
report a snapshot of the current processes.
显示ps命令执行那一刻系统上进程的运行状态。
ps命令查看内核管理进程参数的接口 --> 伪文件系统/proc
进程是由内核管理的,而内核管理进程的相关信息可通过接口来查询,在Linux上这个接口就是/proc目录,内核参数是模拟成文件系统类型的,每个文件即为内核参数。/proc文件系统存放于内存空间中,用于存放内核中的状态信息。
内核参数有两种:
(1)可设置其值从而调整内核运行特性的参数:这些参数通常存放于/proc/sys/目录下,但并非位于 /proc/sys目录下的文件(参数)均可设置,只能设置具有写权限的文件(参数)。 (2)状态参数:用于输出内核中的统计信息和状态信息;仅用于查看。
每个进程在/proc目录下都有一个与其PID同名的目录,这个目录下的每个文件都是内核参数,用于专门保存当前进程的相关信息。
如下,显示init进程对应的目录:
通过参数comm可查看启动该进程的程序文件:
[root@osyunwei ~]# cat /proc/1/comm init
通过参数maps可查看逻辑地址和物理内存地址的映射关系:
[root@osyunwei ~]# cat /proc/1/maps 7f10e779e000-7f10e77ab000 r-xp 00000000 fd:01 398008 /lib64/libnss_files-2.12.so #库函数 7f10e77ab000-7f10e79aa000 ---p 0000d000 fd:01 398008 /lib64/libnss_files-2.12.so 7f10e79aa000-7f10e79ab000 r--p 0000c000 fd:01 398008 /lib64/libnss_files-2.12.so 7f10e79ab000-7f10e79ac000 rw-p 0000d000 fd:01 398008 /lib64/libnss_files-2.12.so 7f10e79ac000-7f10e7b36000 r-xp 00000000 fd:01 462418 /lib64/libc-2.12.so 7f10e7b36000-7f10e7d36000 ---p 0018a000 fd:01 462418 /lib64/libc-2.12.so .....(中间省略)..... 7f10e8c01000-7f10e8c24000 r-xp 00000000 fd:01 149577 /sbin/init 7f10e8e23000-7f10e8e25000 r--p 00022000 fd:01 149577 /sbin/init 7f10e8e25000-7f10e8e26000 rw-p 00024000 fd:01 149577 /sbin/init 7f10eaa25000-7f10eaa64000 rw-p 00000000 00:00 0 [heap] #堆内存 7ffc9a845000-7ffc9a85a000 rw-p 00000000 00:00 0 [stack] #栈内存 7ffc9a8fd000-7ffc9a8fe000 r-xp 00000000 00:00 0 [vdso] ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
因为在/proc目录下的内核参数对于非内核级开发人员来说不便于查看,因此就有诸多查看命令专门将其中这些内核参数信息收集起来并以一种直观的方式显示出来,ps命令就是其中一个比较经典的命令;
ps命令格式:
ps [options]
ps命令选项有三种风格:
(1)UNIX选项:选项之前必须带'-' (2)BSD选项:选项之间不能带'-' (3)GNU长格式选项:选项之前必须带'--'
常用选项:
a:显示所有与终端相关的进程;
x:显示所有与终端无关的进程;
u:以用户为中心组织进程状态信息的显示;
o field1,field2,...:自定义要显示的字段列表;各字段以逗号分隔;
-e:显示所有进程
-f:以完整格式显示进程状态信息;
-F:以完整格式显示进程状态信息(显示项比-f选项更多);
-H:Hierarchy,以层级结构显示进程的相关信息;
进程启动方式:
(1)系统启动过程中自动启动:与终端无关的进程;
(2)用户通过终端启动的进程:与终端相关的进程;
①常用组合之一:aux
显示所有与终端相关的进程:
[root@localhost ~]# ps a PID TTY STAT TIME COMMAND 2571 tty1 Ss+ 0:02 -bash 13604 pts/0 Ss 0:00 -bash 13742 pts/0 R+ 0:00 ps a #各字段意义: PID:进程号; TTY:与进程相关的终端设备; STAT:进程的状态; TIME:进程累积占用CPU的时间; COMMAND:启动该进程的程序命令(包括选项和参数)
显示所有与终端无关的进程:
[root@localhost ~]# ps x PID TTY STAT TIME COMMAND 1 ? Ss 0:28 /usr/lib/systemd/systemd --switched-root --system --deserialize 21 2 ? S 0:00 [kthreadd] 3 ? S 0:00 [ksoftirqd/0] 5 ? S< 0:00 [kworker/0:0H] 7 ? S 0:02 [migration/0] 8 ? S 0:00 [rcu_bh] 9 ? R 0:30 [rcu_sched] 10 ? S 0:00 [watchdog/0] .....(省略)..... 1982 ? Ss 0:12 /usr/sbin/httpd -DFOREGROUND 2571 tty1 Ss+ 0:02 -bash 5213 ? Ssl 0:12 /usr/sbin/NetworkManager --no-daemon 7625 ? S< 0:00 [kworker/1:2H] .....(省略)..... 13739 ? S 0:00 [kworker/3:1] 13740 ? S< 0:00 [kworker/3:2H] 13755 pts/0 R+ 0:00 ps x #'?'表示与终端无关; #根据PID号从小到大排序,各字段意义同上;
显示所有进程:
[root@localhost ~]# ps ax
以用户为中心显示所有进程:
[root@localhost ~]# ps aux USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.0 0.6 193628 6732 ? Ss Feb13 0:28 /usr/lib/systemd/systemd --switched-root --system --des root 2 0.0 0.0 0 0 ? S Feb13 0:00 [kthreadd] root 3 0.0 0.0 0 0 ? S Feb13 0:00 [ksoftirqd/0] root 5 0.0 0.0 0 0 ? S< Feb13 0:00 [kworker/0:0H] root 7 0.0 0.0 0 0 ? S Feb13 0:02 [migration/0] root 8 0.0 0.0 0 0 ? S Feb13 0:00 [rcu_bh] root 9 0.0 0.0 0 0 ? S Feb13 0:30 [rcu_sched] root 10 0.0 0.0 0 0 ? S Feb13 0:00 [watchdog/0] root 11 0.0 0.0 0 0 ? S Feb13 0:00 [watchdog/1] root 12 0.0 0.0 0 0 ? S Feb13 0:03 [migration/1] root 13 0.0 0.0 0 0 ? S Feb13 0:03 [ksoftirqd/1] .....(以下省略)..... #各字段意义: USER:运行进程的用户; PID:进程号; %CPU:进程占用CPU资源的百分比; %MEM:进程占用内存资源的百分比; VSZ:Virtual memory SiZe,虚拟内存集; RSS:ReSident Size,常驻内存集; TTY:与进程相关的终端设备; STAT:进程状态; START:进程的启动时间; TIME:进程累积占用CPU时间; COMMAND:进程由哪个命令程序启动,带'[]'代表为内核线程,而通过pstree命令只能显示进程;
进程状态(STAT):
R:running,运行态; S:interruptable sleeping,可中断睡眠; D:uninterruptable sleeping,不可中断睡眠; T:stopped,停止态; Z:zombie,僵死态; +:前台进程(前台指的是通过终端运行,需要占据命令提示符); l:多线程进程; N:低优先级进程; <:高优先级进程; s:session leader,会话主导者(例如bash);
②常用组合之二:ef
显示所有进程:
[root@localhost ~]# ps -e PID TTY TIME CMD 1 ? 00:00:28 systemd 2 ? 00:00:00 kthreadd 3 ? 00:00:00 ksoftirqd/0 .....(以下省略).....
以完整格式显示进程信息:
[root@localhost ~]# ps -f UID PID PPID C STIME TTY TIME CMD root 13604 13600 0 19:42 pts/0 00:00:00 -bash root 13882 13604 0 21:03 pts/0 00:00:00 ps -f #STIME:进程的启动时间;
以完整格式显示所有进程:
[root@localhost ~]# ps -ef UID PID PPID C STIME TTY TIME CMD root 1 0 0 Feb13 ? 00:00:28 /usr/lib/systemd/systemd --switched-root --system --deserialize 21 root 2 0 0 Feb13 ? 00:00:00 [kthreadd] root 3 2 0 Feb13 ? 00:00:00 [ksoftirqd/0] root 5 2 0 Feb13 ? 00:00:00 [kworker/0:0H] root 7 2 0 Feb13 ? 00:00:02 [migration/0] root 8 2 0 Feb13 ? 00:00:00 [rcu_bh] root 9 2 0 Feb13 ? 00:00:31 [rcu_sched] root 10 2 0 Feb13 ? 00:00:00 [watchdog/0] root 11 2 0 Feb13 ? 00:00:00 [watchdog/1] .....(以下省略)..... #各字段意义: UID:effective user,有效用户,即运行该进程的用户; PID:进程号; PPID:父进程号; C:cpu utilization,CPU使用率,即占用CPU资源的百分比; STIME:进程的启动日期; TTY:与进程相关的终端设备;'?'表示与终端无关; TIME:进程累积占用CPU的时间; CMD:启动进程的命令程序,带'[]'表示为内核线程;
以更为完整的格式显示所有进程:
[root@localhost ~]# ps -eF UID PID PPID C SZ RSS PSR STIME TTY TIME CMD root 1 0 0 48407 6732 3 Feb13 ? 00:00:28 /usr/lib/systemd/systemd --switched-root --system --des root 2 0 0 0 0 0 Feb13 ? 00:00:00 [kthreadd] root 3 2 0 0 0 0 Feb13 ? 00:00:00 [ksoftirqd/0] root 5 2 0 0 0 0 Feb13 ? 00:00:00 [kworker/0:0H] root 7 2 0 0 0 0 Feb13 ? 00:00:02 [migration/0] root 8 2 0 0 0 2 Feb13 ? 00:00:00 [rcu_bh] root 9 2 0 0 0 0 Feb13 ? 00:00:31 [rcu_sched] root 10 2 0 0 0 0 Feb13 ? 00:00:00 [watchdog/0] root 11 2 0 0 0 1 Feb13 ? 00:00:00 [watchdog/1] #各字段意义: UID:运行该进程的用户; PID:进程号; PPID:父进程号; C:CPU使用率; SZ:即VSZ,虚拟内存集; RSS:常驻内存集; STIME:进程的启动日期; TTY:与进程相关的终端设备; TIME:进程累积占用CPU的时间; CMD:启动进程的命令程序;
③常用组合之三:-efH
以层级结构显示进程相关信息:
[root@localhost ~]# ps -efH UID PID PPID C STIME TTY TIME CMD root 2 0 0 Feb13 ? 00:00:00 [kthreadd] root 3 2 0 Feb13 ? 00:00:00 [ksoftirqd/0] root 5 2 0 Feb13 ? 00:00:00 [kworker/0:0H] root 7 2 0 Feb13 ? 00:00:02 [migration/0] root 8 2 0 Feb13 ? 00:00:00 [rcu_bh] root 9 2 0 Feb13 ? 00:00:31 [rcu_sched] root 10 2 0 Feb13 ? 00:00:00 [watchdog/0] root 11 2 0 Feb13 ? 00:00:00 [watchdog/1] root 12 2 0 Feb13 ? 00:00:03 [migration/1] root 13 2 0 Feb13 ? 00:00:03 [ksoftirqd/1] .....(中间省略)..... root 840 1 0 Feb13 ? 00:00:02 /usr/sbin/rsyslogd -n dbus 841 1 0 Feb13 ? 00:00:22 /bin/dbus-daemon --system --address=sys temd: --nofork --nopidfile --s root 854 1 0 Feb13 ? 00:00:00 /usr/sbin/sshd root 13600 854 0 19:42 ? 00:00:01 sshd: root@pts/0 root 13604 13600 0 19:42 pts/0 00:00:00 -bash root 13993 13604 0 21:15 pts/0 00:00:00 ps -efH root 861 1 0 Feb13 ? 00:00:06 /usr/lib/systemd/systemd-logind root 868 1 0 Feb13 ? 00:00:00 /usr/sbin/atd -f root 870 1 0 Feb13 ? 00:00:01 /usr/sbin/crond -n root 884 1 0 Feb13 ? 00:00:00 login -- root root 2571 884 0 Feb13 tty1 00:00:02 -bash .....(以下省略)..... #CMD字段缩进级别相同的进程表示为同级子进程;
④常用组合之四:-eo, axo
o选项:
o field1,field2,...:自定义要显示的字段列表,各字段以逗号分隔; 常见的field有:pid, ppid, ni, pri, rtpri, pcpu, psr, stat, comm(cmd), tty, ... pid:进程号; ppid:父进程号; ni:nice值; priority:优先级; rtpri:实时优先级; psr:运行于哪颗CPU之上; stat:进程状态; cmd:启动该进程的命令程序; tty:与进程相关的终端设备;
显示PID及其对应的命令程序:
[root@localhost ~]# ps axo pid,cmd PID CMD 1 /usr/lib/systemd/systemd --switched-root --system --deserialize 21 2 [kthreadd] 3 [ksoftirqd/0] 5 [kworker/0:0H] 7 [migration/0] .....(以下省略).....
在CentOS 7上显示初始化程序systemd相关进程的PID,优先级和Nice值:
[root@loaclhost ~]# ps axo cmd,pid,priority,ni | grep systemd /usr/lib/systemd/systemd -- 1 20 0 /usr/lib/systemd/systemd-jo 601 20 0 /usr/lib/systemd/systemd-ud 640 20 0 /usr/lib/systemd/systemd-lo 846 20 0
pgrep, pkill命令:
look up or signal processes based on name and other attributes
根据名字或其他属性查看进程或向进程发送信号。
命令格式:
pgrep [options] pattern pkill [options] pattern
常用选项:
-u uid:effective user,显示指定用户运行的进程(运行过程中可切换身份);
-U uid:real user,显示指定用户启动了哪些进程;
-t TERMINAL:显示与终端相关的进程;
-l:显示进程名;
-a:显示完整格式的进程名;
-P pid:显示指定进程的子进程;
用法示例:
显示进程名中包含字符串'ssh'的进程:
[root@localhost ~]# pgrep httpd 1982 1983 1984 1985 1986 1987 1988
显示用户postfix启动了哪些进程:
[root@localhost ~]# pgrep -U postfix 977 14002 #检验: [root@localhost ~]# ps aux | egrep '^USER|977|14002' USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND postfix 977 0.0 0.3 91236 3988 ? S Feb13 0:00 qmgr -l -t unix -u postfix 14002 0.0 0.3 91168 3972 ? S 21:21 0:00 pickup -l -t unix -u root 14184 0.0 0.0 112652 968 pts/0 S+ 22:06 0:00 grep -E --color=auto ^USER|977|14002
显示用户postfix启动的进程的PID和进程名:
[root@localhost ~]# pgrep -U postfix -l 977 qmgr 14002 pickup
显示用户postfix启动的进程的PID和进程名(完整格式):
[root@localhost ~]# pgrep -U postfix -a 977 qmgr -l -t unix -u 14002 pickup -l -t unix -u
pidof命令:
find the process ID of a running program.
根据进程名,找出相应的PID。
用法示例:
显示httpd对应的PID:
[root@localhost ~]# pidof httpd 1988 1987 1986 1985 1984 1983 1982
top命令:
display Linux processes
以动态方式查看当前系统上的进程信息;类似于Windows上的任务管理器;以排序方式显示,占用某种资源最多的进程显示在最前。
常用命令:
排序: P命令:以占据CPU百分比排序;(默认) M命令:以占据内存百分比显示; T命令:以累积占用CPU时间排序; 控制首部字段的开启或关闭: (1)uptime信息:l命令; (2)tasks及cpu信息:t命令; (3)内存信息:m命令; 修改刷新时间间隔:s命令; 终止指定的进程:k命令; 退出top进程:q命令;
常用选项:
-d #:Delay-time interval,指定刷新时间间隔;默认为3秒;
-b:Batch-mode,以批次方式显示;
-n #:Number-of-iterations,指定显示多少批次后退出top进程;
用法示例:
动态查看Linux系统上的进程信息:
[root@localhost ~]# top top - 22:40:29 up 1 day, 9:33, 2 users, load average: 0.00, 0.01, 0.05 Tasks: 203 total, 2 running, 200 sleeping, 1 stopped, 0 zombie %Cpu(s): 0.1 us, 0.1 sy, 0.0 ni, 99.8 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st KiB Mem : 999964 total, 485220 free, 185104 used, 329640 buff/cache KiB Swap: 2097148 total, 2097148 free, 0 used. 598852 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 14293 root 20 0 157708 2284 1556 R 0.3 0.2 0:00.05 top 1 root 20 0 193628 6732 3968 S 0.0 0.7 0:29.74 systemd 2 root 20 0 0 0 0 S 0.0 0.0 0:00.15 kthreadd 3 root 20 0 0 0 0 S 0.0 0.0 0:00.88 ksoftirqd/0 5 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 kworker/0:0H 7 root rt 0 0 0 0 S 0.0 0.0 0:02.20 migration/0 8 root 20 0 0 0 0 S 0.0 0.0 0:00.00 rcu_bh 9 root 20 0 0 0 0 S 0.0 0.0 0:33.04 rcu_sched 10 root rt 0 0 0 0 S 0.0 0.0 0:00.79 watchdog/0 11 root rt 0 0 0 0 S 0.0 0.0 0:00.84 watchdog/1 12 root rt 0 0 0 0 S 0.0 0.0 0:03.81 migration/1 13 root 20 0 0 0 0 S 0.0 0.0 0:03.32 ksoftirqd/1 15 root 0 -20 0 0 0 S 0.0 0.0 0:00.18 kworker/1:0H 16 root rt 0 0 0 0 S 0.0 
当前名称:进程的查看与管理
浏览路径:http://bjjierui.cn/article/pccsod.html