linux---进程---5种状态 012进程 进程管理ps top pstree

1.进程的概念

Linux是一个多用户多任务(即并发)的操作系统。
  多用户是指多个用户可以在同一时间使用同一个linux系统;
  多任务:同时进行多项任务,linux采用了分时管理的方法,所有的任务都放在一个队列中,操作系统根据每个任务的优先级为每个任务分配合适的时间片因此,linux可以在一个任务还未执行完时,暂时挂起此任务,又去执行另一个任务,过一段时间以后再回来处理这个任务,直到这个任务完成,才从任务队列中去除。这就是多任务的概念。
  
  进程的的基本定义是:在自身的虚拟地址空间运行的一个独立的程序,从操作系统的角度来看,所有在系统上运行的东西,都可以称为一个进程。
  需要注意的是:程序和进程是有区别的:

程序:进程指令的集合,它可以启用一个或多个进程,同时,程序只占用磁盘空间,而不占用系统运行资源。
进程:由程序产生,只占用系统内存空间,是动态的、可变的,关闭进程,占用的内存资源随之释放。

2.进程的分类

1、系统进程:可以执行内存资源分配和进程切换等管理工作;而且,该进程的运行不受用户的干预,即使是root用户也不能干预系统进程的运行。
2、用户进程:通过执行用户程序、应用程序或内核之外的系统程序而产生的进程,此类进程可以在用户的控制下运行或关闭。
又可以进一步分类:
 2.1、交互进程:由一个shell终端启动的进程,在执行过程中,需要与用户进行交互操作,可以运行于前台,也可以运行在后台。
 2.2、批处理进程:该进程是一个进程集合,负责按顺序启动其他的进程。
 2.3、守护进程:守护进程是一直运行的一种进程,经常在linux系统启动时启动,在系统关闭时终止。它们独立于控制终端并且周期性的执行某种任务或等待处理某些发生的事件。例如httpd进程,一直处于运行状态,等待用户的访问。还有经常用的crond进程,这个进程类似与windows的计划任务,可以周期性的执行用户设定的某些任务。

进程的5种状态

运行态:该进程正在执行。
就绪态:进程已经做好了准备,只要有机会就开始执行。
阻塞态(等待态):进程缺乏特定条件/状态/数据,满足后才能执行
新建态:刚刚创建的进程,操作系统还没有把它加入到可执行进程组中,通常是进程控制块已经创建但是还没有加载到内存中的进程。
退出态:操作系统从可执行进程组中释放出的进程,或由于自身或某种原因停止运行。
在这里插入图片描述

3.进程的属性

(2)进程之间的关系-----父子------所有者(用户)UID-------同组组GID
在linux系统中,进程ID(用PID表示)是区分不同进程的唯一标识,它们的大小是有限制的,最大ID为32768,用UID和GID分别表示启动这个进程的用户和用户组。所有的进程都是PID为1的init进程的后代,内核在系统启动的最后阶段启动init进程,因而,这个进程是linux下所有进程的父进程,用PPID表示父进程。
下面是通过**ps命令(细节见下面)**输出的sendmail进程信息:

[root@localhost ~]# ps -ef|grep sendmail
UID PID PPID C STIME TTY TIME CMD
root 3614 1 0 Oct23 ? 00:00:00 sendmail: accepting connections

相对于父进程,就存在子进程,一般每个进程都必须有一个父进程,父进程与子进程之间是管理与被管理的关系,当父进程停止时,子进程也随之消失,但是子进程关闭,父进程不一定终止。
如果父进程在子进程退出之前就退出,那么所有子进程就变成的一个孤儿进程,如果没有相应的处理机制的话,这些孤儿进程就会一直处于僵死状态,资源无法释放,此时解决的办法是在启动的进程内找一个进程作为这些孤儿进程的父进程,或者直接让init进程作为它们的父进程,进而释放孤儿进程占用的资源。

012号进程

系统允许一个进程创建新进程,新进程即为子进程,子进程还可以创建新的子进程,形成进程树结构模型。整个linux系统的所有进程也是一个树形结构。
 树根是系统自动构造的,即在内核态下执行的0号进程(idle进程),它是所有进程的祖先。由0号进程创建1号进程(内核态),1号负责执行内核的部分初始化工作及进行系统配置,并创建若干个用于高速缓存和虚拟主存管理的内核线程。随后,1号 进程调用execve()运行可执行程序init,并演变成用户态1号进程,即init进程。它按照配置文件/etc/initab的要求,完成系统启动工作,创建编号为1号、2号…的若干终端注册进程getty。

每个getty进程设置其进程组标识号,并监视配置到系统终端的接口线路。当检测到来自终端的连接信号时,getty进程将通过函数execve()执行注册程序login,此时用户就可输入注册名和密码进入登录过程,如果成功,由login程序再通过函数execv()执行shell,该shell进程接收getty进程的pid,取代原来的getty进程。再由shell直接或间接地产生其他进程。

上述过程可描述为:0号进程->1号内核进程->1号用户进程(init进程)->getty进程->shell进程
注意,上述过程描述中提到:1号内核进程调用执行init(函数)并演变成1号用户态进程(init进程),这里前者是init是函数,后者是进程。两者容易混淆,区别如下:

1.init函数在内核态运行,是内核代码
2.init进程是内核启动并运行的第一个用户进程,运行在用户态下。
3.一号内核进程调用execve()从文件/etc/inittab中加载可执行程序init并执行,这个过程并没有使用调用do_fork(),因此两个进程都是1号进程

Linux下有三个特殊的进程idle进程(PID=0),init进程(PID=1),和kthreadd(PID=2)

idle进程(PID=0):
	系统自动创建,运行在内核态
	其前身是系统创建的第一个进程,也是唯一一个没有通过fork或者kernel_thread产生的进程。完成加载系统后,演变为进程调度、交换。

kthreadd进程:
	由idle通过kernel_thread创建,并始终运行在内核空间,负责【所有内核进程的调度和管理。】
	它的任务就是管理和调度其他内核线程kernel_thread, 会循环执行一个kthread的函数,该函数的作用就是运行kthread_create_list
	全局链表中维护的kthread,当我们调用kernel_thread创建的内核线程会被加入到此链表中,因此所有的内核线程都是直接或者间接的
	以kthreadd为父进程 。


init进程:
由idle通过kernel_thread创建,在内核空间完成初始化后,加载init程序
在这里我们就主要讲解下init进程,init进程由0进程创建,完成系统的初始化,是系统中<strong>所有其他用户进程</strong>的祖先进程
Linux中的所有进程都是由init进程创建并运行的。首先Linux内核启动,然后在用户空间中启动init进程,再启动其他系统进程。
在系统启动完成后,init将变成为守护进程监视系统其他进程。
所以说init进程是Linux系统操作中不可缺少的程序之一,如果内核找不到init进程就会试着运行/bin/sh(还有其他缺省init项)
如果4个缺省都运行失败,系统的启动也会失败。

进程的监控与管理:ps、top、pstree、lsof指令

ps

具体见鸟哥p524 进程管理

ps -ef | grep httpd    其中   | grep httpd     管道    grep httpd只显示httped相关的部分

[root@localhost ~]#ps -ef | grep httpd    
UID       PID  PPID   C STIME TTY         TIME     CMD
nobody    7272 26037  0 Nov06  ?        00:00:00 /apache2/bin/httpd -k start
nobody    7274 26037  0 Nov06  ?        00:00:00 /apache2/bin/httpd -k start
nobody    7400 26037  0 Nov06  ?        00:00:00 /apache2/bin/httpd -k start
root     26037  1     0 Oct23  ?        00:00:00 /apache2/bin/httpd -k start        

[root@localhost ~]# ps auxf | grep httpd
USER      PID  %CPU %MEM    VSZ  RSS  TTY STAT  START   TIME   COMMAND
root     26037  0.0  0.1   6316  2884  ?   Ss   Oct23   0:00 /apache2/bin/httpd -k start
nobody    7272  0.0  0.1   7016  3740  ?   S    Nov06   0:00  \_ /apache2/bin/httpd -k start
nobody    7274  0.0  0.1   7016  3704  ?   S    Nov06   0:00  \_ /apache2/bin/httpd -k start
nobody    7400  0.0  0.1   7012  3676  ?   S    Nov06   0:00  \_ /apache2/bin/httpd -k start

pstree

pstree命令以树形结构显示程序和进程之间的关系,使用格式如下:
pstree [-acnpu] [/]
选项含义如下:
 -a  显示启动每个进程对应的完整指令,包含启动进程的路径、参数等等。
 -c  不使用精简法显示进程信息,即显示的进程中包含子进程和父进程。
 -n  根据进程PID号来排序输出,默认是以程序名称排序输出的。
 -p  显示进程的PID。
 -u  显示进程对应的用户名称。
 PID:即进程对应的PID号,或者叫进程识别号。
 user:系统用户名。
pstree清楚的显示了程序和进程之间的关系,如果不指定进程的PID号,或者不指定用户名称,则将以init进程为根进程,显示系统的所有程序和进程信息,若指定用户或PID,则将以用户或PID为根进程,显示用户或PID对应的所有程序和进程。
举例如下:
如果想知道某个用户下都启动了哪些进程的话,pstree指令可以很容易实现,下面显示mysql用户下对应的进程信息,执行如下命令:
[root@localhost ~]# pstree mysql
mysqld—6*[{mysqld}]
该输出显示了mysql用户下对应的进程为mysqld,并且mysqld进程拥有5个子进程(5个子进程加一个父进程,共6个进程)。
为了更详细的了解每个进程的信息,例如每个子进程和父进程对应的PID,执行如下命令:
[root@localhost ~]# pstree -c -p mysql
mysqld(18785)-±{mysqld}(18787)
|-{mysqld}(18788)
|-{mysqld}(18789)
|-{mysqld}(18790)
|-{mysqld}(18791)
-{mysqld}(29625) 通过“-p、-c”参数,清楚的显示了父进程和子进程,以及它们各种的PID。 如果知道进程对应的PID,想得到进程是由哪个用户启动的,可以执行如下命令: [root@localhost ~]# pstree -u 26037 httpd---10*[httpd(nobody)] 从上面可知,httpd进程是由nobody用户启动的。 如果要查看httpd父进程和每个子进程分别对应的PID,可以执行如下命令组合: [root@localhost ~]# pstree -u -p 26037 httpd(26037)-+-httpd(24562,nobody) |-httpd(24563,nobody) |-httpd(24566,nobody) |-httpd(24567,nobody) |-httpd(24631,nobody) |-httpd(24648,nobody) |-httpd(24650,nobody) |-httpd(24654,nobody) |-httpd(26156,nobody)-httpd(29014,nobody)
如果要得到启动httpd进程的程序路径、参数组合,执行如下命令:
[root@localhost ~]# pstree -a -u -p 26037
httpd,26037 -k start
|-httpd,24563,nobody -k start
|-httpd,24566,nobody -k start
|-httpd,24567,nobody -k start
|-httpd,24631,nobody -k start
|-httpd,24648,nobody -k start
|-httpd,24650,nobody -k start
|-httpd,24654,nobody -k start
|-httpd,26156,nobody -k start
`-httpd,29014,nobody -k start

top

top命令是监控系统进程必不可少的工具,与ps命令相比,top命令动态、实时的显示进程状态,而ps只能显示进程某一时刻的信息,同时,top命令提供了一个交互界面,用户可以根据需要,人性化的定制自己的输出,更清楚的了解进程的实时状态。

下面这个例子是某系统在某时刻执行top命令后的输出:
[root@webserver ~]# top
Tasks: 126 total, 1 running, 123 sleeping, 1 stopped, 1 zombie
Cpu(s): 0.8% us, 0.1% sy, 0.0% ni, 99.0% id, 0.0% wa, 0.0% hi, 0.0% si
Mem: 8306544k total, 8200452k used, 106092k free, 234340k buffers
Swap: 8385888k total, 160k used, 8385728k free, 7348560k cached

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
21115 root 23 0 1236m 360m 2384 S 6 4.4 382:24.14 java
30295 root 16 0 3552 984 760 R 1 0.0 0:00.09 top
30118 nobody 15 0 6904 3132 1676 S 0 0.0 0:00.47 httpd
30250 nobody 15 0 6900 3088 1660 S 0 0.0 0:00.06 httpd
1 root 16 0 1780 552 472 S 0 0.0 0:01.25 init
从top命令的输出可知,此系统有java和httpd两个用户进程在运行。
进程PID为21115的java进程由root用户启动,优先级(PR)为23,占用的虚拟内存总量(VIRT)为1236M,未被换出的物理内存(RES)为360M,共享内存(SHR)为2384 kb。通过这几个选项可以了解java进程对内存的使用量,有助于系统管理员对系统虚拟内存使用状况的掌控。
此刻java进程处于休眠状态(S),从上次更新到现在java占用cpu时间(%CPU)为6%,占用物理内存(%MEM)为4.4%,从进程启动到现在java占用cpu总时间(TIME+)为“382:24.14”,单位是1/100秒。通过了解这些信息,可以使系统管理员掌握java进程对系统CPU、物理内存的使用状况。
两个httpd进程由nobody用户启动,优先级都为15,同时都处于休眠状态。
除去这两个进程,还有top进程,也就是我们执行top命令产生的进程,从进程状态项可知,此进程处于运行状态,另一个是init进程,即所有系统进程的父进程,对应的PID为1。
当然top的输出还有很多进程信息,这里仅仅拿出前几个进程进行重点讲解,理解其它进程的含义基本与这些相同。

lsof

lsof全名list opened files,也就是列举系统中已经被打开的文件,通过lsof,我们就可以根据文件找到对应的进程信息,也可以根据进程信息找到进程打开的文件。

lsof指令功能强大,这里介绍“-c,-g,-p,-i”这四个最常用参数的使用。更详细的介绍请参看man lsof。
 lsof filename:显示使用filename文件的进程。
如果想知道某个特定的文件由哪个进程在使用,可以通过“lsof 文件名”方式得到,例如:
[root@localhost ~]# lsof /var/log/messages
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
syslogd 2027 root 1w REG 8,6 43167 31916 /var/log/messages
从这个输出可知,/var/log/messages文件是由syslogd进程在使用。
 lsof -c abc :显示abc进程现在打开的文件,例如:
[root@localhost ~]# lsof -c nfs
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
nfsd4 2761 root cwd DIR 8,3 4096 2 /
nfsd4 2761 root rtd DIR 8,3 4096 2 /
nfsd4 2761 root txt unknown /proc/2761/exe
nfsd 2762 root cwd DIR 8,3 4096 2 /
nfsd 2762 root rtd DIR 8,3 4096 2 /
nfsd 2762 root txt unknown /proc/2762/exe
nfsd 2763 root cwd DIR 8,3 4096 2 /
nfsd 2763 root rtd DIR 8,3 4096 2 /
nfsd 2763 root txt unknown /proc/2763/exe
上例显示了nfs进程打开的文件信息,FD列表示文件描述符,TYPE列显示文件的类型,SIZE列显示文件的大小,NODE列显示本地文件的node码,NAME列显示文件的全路径或挂载点。
 lsof -g gid:显示指定的进程组打开的文件情况,例如:
[root@localhost ~]# lsof -g 3626
COMMAND PID PGID USER FD TYPE DEVICE SIZE NODE NAME
sendmail 3626 3626 smmsp cwd DIR 8,8 4853760 32714 /var/spool/clientmqueue
sendmail 3626 3626 smmsp rtd DIR 8,10 4096 2 /
sendmail 3626 3626 smmsp txt REG 8,9 732356 1152124 /usr/sbin/sendmail.sendmail
sendmail 3626 3626 smmsp mem REG 8,10 106397 1158794 /lib/ld-2.3.4.so
sendmail 3626 3626 smmsp mem REG 8,10 95148 1175044 /lib/libnsl-2.3.4.so
…省略…
sendmail 3626 3626 smmsp 3u unix 0xf41e5bc0 9592 socket
sendmail 3626 3626 smmsp 4wW REG 8,8 50 523293 /var/run/sm-client.pid
其中,PGID列表示进程组的ID编号。
上面输出,显示了sendmail程序当前打开的所有文件、设备、库及套接字等。
 lsof -p PID:PID是进程号,通过进程号显示程序打开的所有文件及相关进程,例如,想知道init进程打开了哪些文件的话,可以执行“lsof -p 1”命令,输出结果如下:
[root@localhost ~]# lsof -p 1
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
init 1 root cwd DIR 8,10 4096 2 /
init 1 root rtd DIR 8,10 4096 2 /
init 1 root txt REG 8,10 32684 897823 /sbin/init
init 1 root mem REG 8,10 56320 2175328 /lib/libselinux.so.1
init 1 root mem REG 8,10 106397 1158794 /lib/ld-2.3.4.so
init 1 root mem REG 8,10 1454462 1161560 /lib/tls/libc-2.3.4.so
init 1 root mem REG 8,10 53736 1158819 /lib/libsepol.so.1
init 1 root 10u FIFO 0,13 966 /dev/initctl

 lsof -i 通过监听指定的协议、端口、主机等信息,显示符合条件的进程信息。
使用语法为:
lsof -i [46] [protocol][@hostname][:service|port]
 46:4代表IPv4,6代表IPv6。
 protocol:传输协议,可以是TCP或UDP。
 hostname:主机名称或者IP地址。
 service:进程的服务名,例如nfs、ssh、ftp等。
 port:系统中服务对应的端口号。例如http服务默认对应80,ssh服务默认对应22等等。
例如:
显示系统中tcp协议对应的25端口进程信息:
[root@localhost ~]# lsof -i tcp:25
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
sendmail 2252 root 4u IPv4 5874 TCP localhost:smtp (LISTEN)
显示系统中80端口对应的进程信息:
[root@localhost ~]# lsof -i :80
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
httpd 16474 nobody 3u IPv6 7316069 TCP *:http (LISTEN)
httpd 16475 nobody 3u IPv6 7316069 TCP *:http (LISTEN)
httpd 16578 nobody 3u IPv6 7316069 TCP *:http (LISTEN)
显示本机udp协议对应的53端口开启的进程信息:
[root@localhost ~]# lsof -i [email protected]:53
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
named 21322 named 20u IPv4 9130640 UDP localhost:domain
通过lsof命令能够清楚的了解进程和文件以及程序之间的对应关系,熟练掌握lsof的使用,对linux的进程管理有很大帮助。

猜你喜欢

转载自blog.csdn.net/qq_42024067/article/details/100010235