进程管理

进程管理

进程的简单了解

进程和程序的区别

  • 程序是静态概念,本身作为一种软件资源长期保存;而进程是程序的执行过程,是动态概念,有一定的生命期,是动态产生和消亡的。

  • 程序和进程无一一对应关系,一个程序可以由多个时程公用;另一方面,一个进程在活动中有可顺序地执行若干程序。

父子进程的关系

  • 子进程是由一个进程所产生的进程,产生这个子进程的进程称为父进程。

  • 在linux系统中,使用系统调用fork创建进程。Fork复制的内容包括父进程的数据和堆栈段以及父进程的进程环境。

  • 父进程终止,子进程自然终止。

前台进程和后台进程

前台进程

在shell提示处打入命令后,创建一个子进程,运行命令,shell等待命令退出,然后返回到对用户给出提示符。这条命令与shell异步运行,即在前台运行,用户在它完成之前不能执行另一个命令,就是说无法进行其他操作。

后台进程

在shell提示处打入命令,后面加上&,shell创建的子进程运行此命令,但是不等待命令退出,而是直接返回到对用户给出提示。这条命令与shell同步运行,在这个进程进行的同时,我们还可以做其他操作。【后台进程必须是非交互式的】

进程的状态

进程的状态

  • 就绪状态
  • 运行状态
  • 等待状态

    进程的状态转换

进程是操作系统为了控制多个程序而创建的数据,操作系统是通过修改进程的状态来完成对相应程序的控制,用户程序的一些操作也可以修改一些进程的状态。

进程三态转换图解析
![进程三态转换图](http://7xo95f.com1.z0.glb.clouddn.com/%E8%BF%9B%E7%A8%8B%E4%B8%89%E6%80%81%E8%BD%AC%E6%8D%A2%E5%9B%BE.jpg)

注意:创建和退出不是进程的状态。创建操作不做重点解释。阻塞也叫等待,和就绪的区别:等待是等待除CPU以外的资源,而就绪等待的是CPU资源。

(1) 创建—–就绪:用户发出命令,我要运行这个程序,然后,操作系统会就会创建进程,并为它分配资源(主要是内存空间),进程创建成功,此时把该进程插入到就绪队列中;

(2) 就绪——执行:对就绪状态的进程,当进程调度程序按一种选定的策略从中选中一个就绪进程,为之分配了处理机后,该进程便由就绪状态变为执行状态;

(进程的就绪状态的意思是,告诉操作系统我现在可以执行了,给我CPU让我运行吧; 操作系统的一个程序给就绪队列中的进程分配一定的时间让他们轮流占用CPU资源,一个就绪进程得到CPU资源后,就变成了运行状态)

(3) 执行——等待:正在执行的进程因发生某等待事件而无法执行,则进程由执行状态变为等待状态,如进程提出输入/输出请求而变成等待外部设备传输信息的状态,进程申请资源(主存空间或外部设备)得不到满足时变成等待资源状态,进程运行中出现了故障(程序出错或主存储器读写错等)变成等待干预状态等等;

(CPU执行某进程中的指令要求调用某一资源时,且该资源别的进程正在用,那么操作系统的这个程序会把该进程的状态变为阻塞状态,例如:指令要求用打印机,但是打印机正在打印东西,无法现在用,那么,操作系统会修改该进程的状态,并把他由就绪队列变为阻塞队列中)

(4)等待——就绪:处于等待状态的进程,在其等待的事件已经发生,如输入/输出完成,资源得到满足或错误处理完毕时,处于等待状态的进程并不马上转入执行状态,而是先转入就绪状态,然后再由系统进程调度程序在适当的时候将该进程转为执行状态;

(循环至正常运行结束,进程中有一些事后处理的指令,会把队列中的记录去掉)

(5)执行——就绪:正在执行的进程,因时间片用完而被暂停执行,或在采用抢先式优先级调度算法的系统中,当有更高优先级的进程要运行而被迫让出处理机时,该进程便由执行状态转变为就绪状态。

进程的五态转换图

进程五态状态装换图

【注意】:在进程的五态图中引入了挂起和激活的操作,另外,进程创建时可以先到静止就绪(主要是内存资源不足),其他的和三态图的操作一样。

  • 挂起:把该进程从内存中搬到外存上。

  • 激活:又叫唤醒或恢复,操作是一样的,只是叫法不一样而已,该操作是把外存上的某个进程弄到内存上。

为什么要引入挂起和激活操作呢?

(1) 用户的需要。用户调试一个程序的时候,运行该程序一多半了,但是,忽然发现该程序此时有Bug,用户想停下来修改,但是修改后,用户又不想从头开始运行该程序,此为一因。这样用户就可以先挂起进程,再次运行时,再激活就好啦!

(2) 操作系统的需要。操作系统管理着资源的分配,它无法忍受那些占着资源而不运行的程序,另外,这些进程也会妨碍系统的运行速度,此为一因。

进程管理命令介绍

w查看当前系统信息

w命令,查看当前用户信息(即谁登陆过我的系统),当然也可以查看到系统相关的信息。

作用:查看当前系统活动摘要。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
[root@foundation187 ~]# w
21:58:49 up 5 min, 2 users, load average: 0.85, 1.31, 0.67
USER TTY LOGIN@ IDLE JCPU PCPU WHAT
kiosk :0 21:54 ?xdm? 50.46s 0.04s gdm-session-worker [pam/gdm-autologin]
kiosk pts/0 21:56 1.00s 0.07s 0.58s /usr/libexec/gnome-terminal-server
```
w显示信息的含义:

JCPU: 以终端代号来区分,该终端所有相关的进程执行时,所消耗的CPU时间会显示在这里

PCPU: CPU执行程序消耗的时间

WHAT: 用户在执行的操作

load average :分别显示系统在过去1515分钟内的平均负载程度

FROM: 显示用户从何处登录系统,":0"的显示代表该用户是从X Windows下,打开文本模式窗口登录的

IDLE: 用户闲置的时间,这是一个计时器,一旦用户执行任何操作,该计时器便会被重置

查看个别用户信息:w [用户名]
[root@localhost ~]# w root

23:32:01 up 52 min, 1 user, load average: 0.00, 0.00, 0.00

USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT

root pts/1 192.168.203.1 22:53 0.00s 0.10s 0.01s w root
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

【注】
last 谁登陆过我的系统

lastb 谁登陆过我的系统,即使没有登陆成功也会记录下来

who是类似命令,提供当前登录用户列表、系统启动时间、运行级别等

whoami 命令输出当前用户

###ps进程查看命令

ps应该是查看进程用得最普遍的命令

进程查看命令:ps

常用选项:
-a:显示所有用户的进程(all)

-u:显示用户名和启动时间(user)

-x:显示没有控制终端的进程

-e:显示所有进程,包括没有控制终端的进程

-l:长格式显示

-f 显示进程的子进程

-w:宽行显示,可以使用多个w进行加宽显示 
1
2
3
应用实例:

eg1. ps 查看隶属自己的进程

[root@foundation187 ~]# ps
PID TTY TIME CMD
1951 pts/0 00:00:00 su
1954 pts/0 00:00:00 bash
2287 pts/0 00:00:00 ps

1
eg2. -l显示更多信息

[root@foundation187 ~]# ps -l
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
4 S 0 1951 1916 0 80 0 - 45691 wait pts/0 00:00:00 su
4 S 0 1954 1951 0 80 0 - 29165 wait pts/0 00:00:00 bash
0 R 0 2302 1954 0 80 0 - 30315 - pts/0 00:00:00 ps

1
eg3. 常用的组合

[root@foundation187 ~]# ps -aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.1 50544 4280 ? Ss 21:53 0:00 /usr/lib/systemd/systemd –swit
root 2 0.0 0.0 0 0 ? S 21:53 0:00 [kthreadd]
root 3 0.0 0.0 0 0 ? S 21:53 0:00 [ksoftirqd/0]
root 5 0.0 0.0 0 0 ? S< 21:53 0:00 [kworker/0:0H]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
看一下上面的选项都指的什么

PID:进程号

PPID: 父进程的进程号

TTY : 进程启动的终端

STAT : 进程当前状态(S休眠状态,D不可中断的休眠状态,R运行状态,Z僵死状态,T停止)

NI : 进程优先级

TIME:进程自从启动以后启用CPU的总时间

COMMAND/CMD:进程的命令名

USER:用户名

%CPU:占用CPU时间和总时间的百分比

%MEM:占用内存与系统内存总量的百分比

常用实例:

* 只查看cpu 并按数字(n) 逆序(从大到小排序
[root@vm1 ~]# ps -o %cpu | sort -nr
1
* 如果分隔符的空格数是不同的,则不能用`sort  -t `分隔符来排序了。这时候可以用awk来辅助。

[root@vm1 ~]# ps aux | grep -v % | awk ‘{print $2”:”$3}’ | sort -t “:” -k 2 -rn

1
* ps -u or -l 查看隶属于自己进程详细信息

[root@foundation187 ~]# ps -u
[root@foundation187 ~]# ps -l

1
* ps -le or -aux 查看所有用户执行的进程的详细信息

[root@foundation187 ~]# ps -le
[root@foundation187 ~]# ps -aux

1
* ps -aux --sort pid 可按进程执行的时间、PID、UID等对进程进行排序

[root@foundation187 ~]# ps -aux –sort pid

[root@foundation187 ~]# ps -aux –sort uid

1
* ps -le | grep init 查看指定进程信息

[root@foundation187 ~]# ps -le | grep init

1
2
3
4
5
6
7
8
9
10
11
12
13
14

### pstree可视化方式显示进程

linux中,每一个进程都是由其父进程创建的。此命令以可视化方式显示进程,通过显示进程的树状图来展示进程间关系。

Rhel6.5中,如果指定了pid了,那么树的根是该pid,不然将会是init(pid:1

Rhel7.0中,如果指定了pid了,那么树的根是该pid,不然将会是systemd(pid:1

### top查看进程命令(类似与ps)

top是一个更加有用的命令,可以监视系统中不同的进程所使用的资源。它提供实时的系统状态信息。显示进程的数据包括 PID、进程属主、优先级、%CPU、%memory等。可以使用这些显示指示出资源使用量。

常用命令:

B 控制正在被执行的进程,是否被粗显。
b 控制正在被执行的程序,是否反白显示
P 按CPU的使用排序(默认情况下是这样子的)
M 按内存的使用排序
U u 都是按用户进行过滤
k 杀死一个进程 会提示你输入进程号
r 给进程重新指定优先级
W 保存对top命令显示的样式的设置,将当前设置写入~/.toprc文件中
s 改变刷新的时间间隔
q 退出top命令
h or ? 获得帮助

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
### htop(类似top)

htop与top很类似,但是htop是交互式的文本模式的进程查看器。它通过文字图形化地显示每一个进程的CPU和内存使用量、swap使用量。使用上下光标键选择进程,F7和F8改变优先级,F9杀死进程。Htop不是系统默认安装的,所以需要额外安装。请参考文章【linux下取代top命令的htop】

### nice通过给定优先值启动一个进程

通过nice命令的帮助,用户可以设置和改变进程的优先级。提高一个进程的优先级,内核会分配更多CPU时间片给这个进程。默认情况下,进程以0的优先级启动。进程优先级可以通过top命令显示的NI(nice value)列查看。

进程优先级值的范围从[-20,19]。值越低,优先级越高,-20的优先级最高,在我们设置优先级为-30的时候,系统默认为-20

`nice <优先值> <进程名> #通过给定的优先值启动一个进程`

格式:nice -n command

`nice -n -20 top #以-20的优先级启动top进程,进去后顺便查看top的NI是否为-20 `

### renice改变正在运行的进程优先级

renice命令类似nice命令。使用这个命令可以改变正在运行的进程优先值。注意,用户 只能改变属于他们自己的进程的优先值。

```
renice -n pid #改变指定进程的优先值

renice -u -g #通过指定用户和组来改变进程优先值
```
eg.

【注】:这里我使用的是虚拟机vm1做实验,运用前面所学习的screen命令,使得top进程一直运行

[root@vm1 ~]# ps -le | grep top #查看top的优先级NI为0
4 S 0 1175 1166 0 80 0 - 3753 poll_s pts/1 00:00:00 top
[root@vm1 ~]# renice -5 1175 #查看top的进程号为1175,在这里将它的优先级修改为-5
1175: old priority 0, new priority -5
[root@vm1 ~]# ps -le | grep top #再次查看,已经改为-5
4 S 0 1175 1166 0 75 -5 - 3753 poll_s pts/1 00:00:00 top

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

### kill终止进程

在linux下,我们可以使用kill命令来终止进程。

#### 杀死进程的原因

* 该进程用了过多的CPU时间

* 该进程锁住了一个终端,使其他前台进程无法运行

* 运行时间过长,但没有预期效果

* 产生了过多到屏幕或磁盘文件的输出

* 无法正常退出

#### kill用法

kill -1 进程pid ##进程重读配置
-2 进程pid ##撤销录入内存中的数据
-3 进程pid ##撤销内存中的鼠标显示
-9 进程pid ##强制关闭进程
-15 进程pid ##正常关闭进程
-18 进程pid ##激活休眠的进程
-19 进程pid ##使进程休眠
-20 进程pid ##使占用终端的进程进入后台休眠

1
2
3
4
5
6
7
#### 其他

* 关闭图形程序: xkill

当你在终端下输入这个命令时,你的鼠标会变成一个小叉子,你只去点你想要关闭的窗口就可以关闭了

* 结束所有进程killall

killall -1 进程名称
-2
-3
-9
-15
-18
-19
-20

1
2
3
4
   
【注】:各选项的作用如同kill

* 查找服务进程号pgrep

pgrep [服务名称]

pgrep httpd

1
2

* 关闭进程pkill [进程名称]

pkill [进程名称]

pkill httpd

1
2
3
### fg,bg(前后台运行,终止与挂起)

有时,命令需要很长的时间才能执行完成。对于这种情况,`jobs`可以查看当前终端的进程,`bg`命令可以将任务放在后台执行,`fg`可以调到前台来使用。

[root@vm1 ~]# cat #ctrl + z 把进程打入后台运行,并停止或者说挂起。进程的状态是Stopped
^Z
[2]+ Stopped cat

[root@vm1 ~]# sleep 1000 & #&释放终端 让进程在后台运行,状态是Running(类似与bg
[1] 6344

[root@vm1 ~]# jobs #Jobs 查看当前终端的进程
[1]- Running sleep 1000 &
[2]+ Stopped cat

1
`[ ]`里的号码就是进程在当前终端的序号

[root@vm1 ~]# fg 1 #使进程1在前台运行
sleep 1000

[root@vm1 ~]# bg 2 #使进程2在后台运行
[2]+ cat &

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

终止:(ctrl+c)

### ulimit

该命令用于控制系统资源在shell和进程上的分配量。对于系统管理员是最有用的,可以管理重度使用和存在性能问题的系统。限制资源大小可以确保重要进程持续运行,其他进程不会占用过多资源。

ulimit -a -显示当前用户关联的资源限制

-f -最大文件尺寸大小
-v -最大虚拟内存大小(KB
-n -增加最大文件描述符数量
-H :改变和报告硬限制
-S :改变和报告软限制

### nohup

nohup命令可以在用户退出时继续执行某一进程

一般的命令在用户退登录后就停止执行了,nohup命令可以使进程在用户退出登录后仍旧继续执行。nohup命令将执行后的数据信息和错误信息默认存储到文件nohup.out中

格式:

nohup program &

eg.

[root@vm1 mnt]# nohup find / -name init* > /mnt/file &
[1] 6377

1
2
3
4
5
6
7
8
9
10
如果我们没指定/mnt/file这个保存位置的话,系统默认会把查询的结果放到nohup.out的文件中。我们一般不会去使用默认方式保存。
## 计划任务

### 设置计划任务的原因

我们在系统的管理中,很多时候不是及时的去操作,比如对某一网站数据的备份,备份的过程需要占用大量的系统资源,凌晨三四点的时候系统访问用户最少,系统最空闲。但我们的系统的系统管理员总不能老那个时间爬起来操作吧。

### 计划任务的命令

计划命令分一次性计划和周期性计划。
at    安排作业在某一时刻执行一次

batch  安排作业在系统负载不重时执行一次

crontab    安排周期性运行的作业
1
2
3
4
5
* 一次性计划at和batch

at命令指定时间的方式

绝对计时方法:
midnight noon teatime

hh:mm [today]

hh:mm tomorrow

hh:mm 星期

hh:mm MM/DD/YY
1
2
3
4
5
6
7
8
相对计时方法:

```
now+n minutes

mow+n hours

now+n days

用法:

指定在今天下午17:30执行某命令(假设现在时间是下午14:30,2016年2月2日)

命令格式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
    at 5:30pm

at 17:30

at 17:30 today

at now+3 hours

at now+180 minutes

at 17:30 16.2.2

at 17:30 2.2.16

```
我们定的时间是5分钟之后,可以在at下面输入各种任务,保存!5分钟之后执行;不过,我们需要注意,在用命令时最好写命令的绝对路径,为了安全。
[root@vm1 ~]# at now+5 minutes

at>touch /mnt/file   

at>                   #可以继续写其它的计划

at> <EOT>            # ctrl+d保存计划并退出

job 2 at 2012-05-20 13:43

1
是否还担心我们的计划是否启动,通过下面两个命令查看at进程是否正常启动

[root@vm1 ~]# at -l
[root@vm1 ~]# atq

如果真的没有启动的话,可以通过手工方式重新启动一下

[root@vm1 ~]# /etc/init.d/atd start
1
* 删除at计划任务

[root@vm1 ~]# at -d

1
* 查看at计划任务

[root@vm1 ~]# ls /var/spool/at/

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
batch命令

作用:

安排一个或多个命令在系统负载较轻进运行一次(一般情况下负载较轻指平均负载降到0.8以下)

使用方法同at

* 周期性计划命令crontab

作用:用于生成cron进程所需要的crontab文件

crontab的命令格式

crontab {-l|-r|-e}

-l 显示当前的crontab

-r 删除当前的crontab

-e 使用编辑器编辑当前crontab文件

好多人都觉得周期计划任务设置起来比较麻烦,其实我们只要掌握规律就很好设置。

`crontab -e`

规则: 把知道的具体的时间添上,不知道的都添加上*

分钟 小时 天 月 星期 命令/脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
eg1.我们每天早上4点要做一下操作,以下面方式表示:

` * 4 * * * [具体的操作]`

eg2. 我们每周一和三下午的6点要做一下操作,以下面方式表示:

`* 18 * * 1,3 [具体的操作]`

案例:在上学的时候都有上机课,周一到周五,下午530下课。我们需要在530发一个通知,545自动关机。设定计划任务需要分两步完成,第一步提醒,第二步关机

分钟 小时 天 月 星期 命令/脚本

30 17 * * 1-5 提醒脚本

45 17 * * 1-5 /usr/bin/shudown -h now

操作方法:

`crontab: installing new crontab` 表示创建计划成功

通过下面方式进行查看计划:

[root@vm1 ~]# cd /var/spool/cron

[root@vm1 ~]# ls

root

[root@vm1 ~]# cat root

30 17 * * 1-5 /usr/bin/shudown -h now  计划任务

```