进程管理

进程可以理解为程序正在运行的过程,管理的内容主要包括程序什么时候启动,程序运行的整个生命周期需要多少资源,包括需要多少内存资源,运行是需要多少CPU资源,运行结束是需要自己结束还是被其他程序结束的,还有程序运行时我们需要让他结束应该怎么让它结束等等

进程的概念及进程查看

进程是运行中的程序,从程序开始运行到终止的整个生命周期是可管理的

C程序的启动时从main函数开始的,包括Java等,终止的方式并不唯一,分为正常终止和异常终止:

  1. 正常终止也分为从main返回,调用exit等方式
  2. 异常终止分为调用abort、接收信号等。当程序获取不到资源比如内存、CPU资源等,会调用abort函数来终止程序

ps命令

使用方法:ps [选项]

单独使用ps命令,它只能查看到当前终端既当前shell下面能够查看到的进程状态,并不是真的只有这些进程在运行,如下只查看到两条:

1
2
3
4
[root@iZm5ehzqow4ijp2ya2g2drZ etc]# ps
PID TTY TIME CMD
27267 pts/0 00:00:00 bash
27342 pts/0 00:00:00 ps
  • PID:表示进程在系统中运行的唯一表示,注意进程的名称是可以重复的,但是PID不能重复

  • TTY:表示执行当前进程的终端,那么当前执行是一个虚拟终端,所以叫 pts/0

  • TIME:程序的运行时间,此项不具有参考价值,可以不用关注

  • CMD:命令

ps选项说明

  • -e 查看所有的进程,这样我们查出来的会非常多,我们可以通过 more 命令来进行分页查看,具体使用为:ps -e | more,这里主要是通过管道符,将管道符左边的输出传递给more,示例如下:
1
2
3
4
5
6
7
8
9
root@iZm5ehzqow4ijp2ya2g2drZ etc]#  ps -e | more
PID TTY TIME CMD
1 ? 00:00:00 init
2 ? 00:00:00 kthreadd
3 ? 00:00:00 migration/0
4 ? 00:00:01 ksoftirqd/0
5 ? 00:00:00 stopper/0
6 ? 00:00:02 watchdog/0
7 ? 00:01:35 events/0

注意我们看到的1号进程,此进程在CentOS6中叫init,在CentOS7中叫systemd

  • -f 表示显示全格式,既对进程的信息显示更加完善,一般是结合-e选项来使用,ps -ef | more
1
2
3
4
5
6
UID        PID  PPID  C STIME TTY          TIME CMD
root 1 0 0 Sep14 ? 00:00:00 /sbin/init
root 2 0 0 Sep14 ? 00:00:00 [kthreadd]
root 3 2 0 Sep14 ? 00:00:00 [migration/0]
root 4 2 0 Sep14 ? 00:00:01 [ksoftirqd/0]
root 5 2 0 Sep14 ? 00:00:00 [stopper/0]

UID表示此进程是哪一个用户来启动的,但是注意,进程启动的用户是可以修改的,所以它的专业名称叫有效用户ID

PPID是父进程,因为我们的程序在启动时都要集成它的父进程的一些信息下来,Linux的第一个进程是1号进程,既init进程

  • -L 查看更详细的进程情况,既可以查看到当前进程中包含了多少个线程,通过此选项我们可以查看到当前进程运行缓慢是不是因为并发太大及线程太多导致的,一般使用也是结合着-ef,具体:ps -eLf | more
1
2
3
4
5
6
UID        PID  PPID   LWP  C NLWP STIME TTY          TIME CMD
root 1 0 1 0 1 Sep14 ? 00:00:00 /sbin/init
root 2 0 2 0 1 Sep14 ? 00:00:00 [kthreadd]
root 3 2 3 0 1 Sep14 ? 00:00:00 [migration/0]
root 4 2 4 0 1 Sep14 ? 00:00:01 [ksoftirqd/0]
root 5 2 5 0 1 Sep14 ? 00:00:00 [stopper/0]

LWP表示的既是线程数量

pstree命令

pstree命令是将进程用树形表示出来,上述ps命令中,我们能查看到进程的父进程,在使用此命令时,我们可以看到一个树形结构的进程图,方便我们查看进程的依属关系,示例如下:

1
2
3
4
5
6
7
8
9
root@iZm5ehzqow4ijp2ya2g2drZ etc]# pstree | more
init-+-AliYunDun---17*[{AliYunDun}]
|-AliYunDunUpdate---3*[{AliYunDunUpdat}]
|-agetty
|-aliyun-service---2*[{aliyun-service}]
|-auditd---{auditd}
|-crond
|-dhclient
|-java---28*[{java}]

top命令

top命令能显示系统的信息及进程信息,类似于Windows的任务管理器,也是一个日常非常实用的命令,可以不带参数,使用具体如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
[root@iZm5ehzqow4ijp2ya2g2drZ etc]# top
top - 17:38:41 up 22 days, 7:54, 2 users, load average: 0.00, 0.00, 0.00
Tasks: 78 total, 1 running, 77 sleeping, 0 stopped, 0 zombie
Cpu(s): 0.3%us, 0.3%sy, 0.0%ni, 99.3%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Mem: 1019980k total, 732792k used, 287188k free, 138988k buffers
Swap: 0k total, 0k used, 0k free, 230192k cached

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1407 root 10 -10 121m 11m 9176 S 0.3 1.2 94:59.64 AliYunDun
27417 root 20 0 15012 1292 1004 R 0.3 0.1 0:00.01 top
1 root 20 0 19228 1508 1232 S 0.0 0.1 0:00.72 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

说明:

  • top

    up 22 days: 当前系统上一次开机到现在运行的时长

    users:当前系统有两个用户已经登录了

    load average: 0.00, 0.00, 0.00: 平均负载,全都是0.00表示空负载,数值越大负载越高,都是1表示满负载运行,平均负载是一分钟进行一次汇总的结果,第一个数字是1分钟的数据,中间数据时5分钟的数据,最后一个是15分钟的统计数据,此数据是查看系统繁忙程度的指标数据

  • Tasks:

    78 tota:系统中有多少个任务正在运行,这里系统将进程表示为任务

    1 running,  77 sleeping,   0 stopped,   0 zombie:一个进程在运行中,77个在休眠状态中。。
  • Cpu(s):

    0.3%us: 0.3%的资源用于用户状态的计算

    0.3%sy: 进程的状态交互占用的资源

    99.3%id:空闲的CPU资源

    0.0%wa:磁盘IO占用的资源

Cpu(s)是说统计的是一个整体情况,如果我们是多核的,可以按下数字键1来分别查看每一个CPU的运行状况,再次按下数字1即可恢复成整体模式

1
2
3
4
5
6
7
8
9
10
11
12
top - 17:54:45 up 1 min,  0 users,  load average: 0.52, 0.58, 0.59
Tasks: 4 total, 1 running, 3 sleeping, 0 stopped, 0 zombie
%Cpu0 : 5.4 us, 8.0 sy, 0.0 ni, 84.0 id, 0.0 wa, 2.6 hi, 0.0 si, 0.0 st
%Cpu1 : 2.0 us, 3.0 sy, 0.0 ni, 95.1 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu2 : 5.6 us, 10.8 sy, 0.0 ni, 83.6 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu3 : 3.0 us, 3.0 sy, 0.0 ni, 94.1 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu4 : 4.6 us, 3.0 sy, 0.0 ni, 92.4 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu5 : 2.3 us, 0.3 sy, 0.0 ni, 97.4 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu6 : 1.6 us, 2.0 sy, 0.0 ni, 96.4 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu7 : 1.6 us, 14.8 sy, 0.0 ni, 83.6 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 16670136 total, 9322736 free, 7118048 used, 229352 buff/cache
KiB Swap: 15518328 total, 15430616 free, 87712 used. 9418356 avail Mem
  • Mem:

    1019980k total:总共有多少内存

    732792k used:已经使用了的内存

    287188k free:空闲的内存

    138988k buffers:读写缓存使用的内存

  • Swap:交换分区,当内存不够用的时候,需要使用交换分区的内存

    0k used:这里只需要关注此选项即可,因为在内存占用比较大的时候才会与系统进行交换分区内存,这里有占用说明程序占用内存很大了

  • 进程信息:

    这里的进程信息我们可以看到还显示了每个进程当前的CPU占用率,以及内存占用情况,默认是3秒已刷新,我们还可以修改刷新时间,使用按键s,即可输入你需要的刷新间隔时间,然后回车,注意单位是秒,这样既可以按照你输入的时间间隔来刷新

    进程信息中PR表示进程的系统优先级,NI表示Nice值,可以理解为此进程占用了多少系统资源,%CPU表示进程占用的CPU资源百分比

参数说明

  • -p 使用-p参数然后指定进程id可以只查看指定id的进程信息,使用示例:
1
2
3
4
5
6
7
8
9
[root@iZm5ehzqow4ijp2ya2g2drZ ~]# top -p 35
top - 16:33:23 up 29 days, 6:49, 2 users, load average: 0.00, 0.00, 0.00
Tasks: 1 total, 0 running, 1 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: 1019980k total, 758240k used, 261740k free, 139084k buffers
Swap: 0k total, 0k used, 0k free, 239196k cached

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
35 root 25 5 0 0 0 S 0.0 0.0 0:00.00 ksmd

进程的优先级调整

进程的优先级我们可以通过查看进程的信息来具体查看,进程信息的NI选项就表示进程的优先级,NI的值在 -20 ~ 19 之间,值越小,优先级越高,抢占资源就越多,一般我们启动的程序默认的优先级是0

使用nice命令修改启动进程的优先级

我们首先启动一个程序,查看它的进程信息如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 第一个终端启动此自定义进程
[root@iZm5ehzqow4ijp2ya2g2drZ home]# ./test.sh
2946

# 重新打开一个终端,查看此进程的信息
[root@iZm5ehzqow4ijp2ya2g2drZ ~]# top -p 2946
top - 17:14:15 up 29 days, 7:29, 3 users, load average: 0.89, 0.85, 0.55
Tasks: 1 total, 1 running, 0 sleeping, 0 stopped, 0 zombie
Cpu(s):100.0%us, 0.0%sy, 0.0%ni, 0.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Mem: 1019980k total, 760396k used, 259584k free, 139088k buffers
Swap: 0k total, 0k used, 0k free, 239332k cached

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
2946 root 20 0 103m 1332 1152 R 99.9 0.1 0:53.76 test.sh

我们看到此进程的NI值为0,CPU的占用率达到了100%,因为我们这个程序一直在循环执行中,然后我们停止此程序,然后使用nice命令指定优先级

nice命令使用方法:nice -n [优先级值] ./应用程序

使用示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 使用第一个终端启动自定义的应用程序并指定进程优先级为15
[root@iZm5ehzqow4ijp2ya2g2drZ home]# nice -n 15 ./test.sh
2953

# 使用第二个终端查看此进程信息
[root@iZm5ehzqow4ijp2ya2g2drZ ~]# top -p 2953
top - 17:12:54 up 29 days, 7:28, 3 users, load average: 0.92, 0.84, 0.52
Tasks: 1 total, 1 running, 0 sleeping, 0 stopped, 0 zombie
Cpu(s): 0.0%us, 0.0%sy,100.0%ni, 0.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Mem: 1019980k total, 760396k used, 259584k free, 139088k buffers
Swap: 0k total, 0k used, 0k free, 239332k cached

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
2953 root 35 15 103m 1332 1152 R 99.6 0.1 1:42.75 test.sh

通过更改程序的优先级来启动程序,我们发现更改后的此进程NI值就变成了我们设置的值,并且很明显的区别就是CPU占用率,我们将优先级值调大之后,CPU占用率在0.0% - 0.3%摆动,表示资源占用急剧下降,所以我们指定程序的优先级是很有效果的一个操作

使用renice命令修改进程的优先级

nice命令有一个问题,我们一般程序在运行中不会终止,上述更改优先级需要将程序停止然后重新指定优先级后启动,这个问题怎么解决呢? 使用renice命令就可以解决,可以在程序运行中直接修改,无需重启

使用方法:renice -n [优先级值] ./应用程序

使用示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 第一个终端启动此自定义进程
[root@iZm5ehzqow4ijp2ya2g2drZ home]# ./test.sh
2966

# 使用第二个终端查看此进程的信息
[root@iZm5ehzqow4ijp2ya2g2drZ ~]# top -p 2966
...
Cpu(s):100.0%us, 0.0%sy, 0.0%ni, 0.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
2966 root 20 0 103m 1332 1152 R 99.7 0.1 0:47.87 test.sh

# 使用第三个终端使用renice修改此进程的优先级值为18
[root@iZm5ehzqow4ijp2ya2g2drZ ~]# renice -n 18 2966
2966: old priority 0, new priority 18

# 切换回第二个终端查看此进程信息,我们发现进程的优先级已经被修改,且程序并没有停止
[root@iZm5ehzqow4ijp2ya2g2drZ ~]# top -p 2966
...
Cpu(s): 0.0%us, 0.0%sy,100.0%ni, 0.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
2966 root 38 18 103m 1332 1152 R 99.6 0.1 5:07.68 test.sh

进程的启动前台后台切换

程序后台启动

我们上述启动程序发现程序一直在终端显示,无法输入其他命令,此终端不能进行其他操作,这种启动的方式叫做前台启动,后台启动就是程序是后台运行的,不影响我们在终端进行操作

后台启动程序的方式是在启动程序命令后 加 & ,使用示例:

1
2
3
4
5
6
7
8
9
[root@iZm5ehzqow4ijp2ya2g2drZ home]# ./test.sh &
[3] 3019
[root@iZm5ehzqow4ijp2ya2g2drZ home]# 3019
ls
test.sh
[root@iZm5ehzqow4ijp2ya2g2drZ home]# top -p 3019
...
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
3019 root 20 0 103m 1332 1152 R 49.9 0.1 0:14.74 test.sh

通过示例我们发现,启动程序后终端返回了程序的进程ID,然后我们就可以在此终端上进行任意其他操作

后台运行程序切换回前台运行

有时候我们需要将后台运行的程序切换回前台运行,可以使用 jobs命令查询出所有的后台程序,然后根据后台运行编号使用fg命令切换回来,使用如下:

1
2
3
4
[root@iZm5ehzqow4ijp2ya2g2drZ home]# jobs
[3]+ Running ./test.sh &
[root@iZm5ehzqow4ijp2ya2g2drZ home]# fg 3
./test.sh

我们发现程序就恢复前台运行了,此时可以通过 CTRL + C 来终止此程序

前台运行程序切换到后台运行

使用 CTRL + Z 可以将前台运行程序切换为后台运行,但是使用此命令切换到后台运行,程序就不是运行的状态了,而是一个暂停运行的状态,它保存在了内存中

使用示例:

1
2
3
4
5
# 首先前台启动进程,然后使用 CTRL + Z 将程序转为后台运行,并且提示你程序为Stopped状态,既停止运行的状态
[root@iZm5ehzqow4ijp2ya2g2drZ home]# ./test.sh
3043
^Z
[4]+ Stopped ./test.sh

上述示例我们发现程序进入后台运行但是是停止状态,我们需要让程序继续运行怎么办?使用jobs命令,然后使用 fg 将程序切换为前台运行或者使用 bg 将程序切换为后台运行

切换为前台运行我们上面已经有过示例了,现在我们示例切换为后台运行,完整示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
# 前台运行程序然后切换为后台暂停运行
[root@iZm5ehzqow4ijp2ya2g2drZ home]# ./test.sh
3050
^Z
[5]+ Stopped ./test.sh

# 将程序切换为后台运行
[root@iZm5ehzqow4ijp2ya2g2drZ home]# jobs
[5]+ Stopped ./test.sh
[root@iZm5ehzqow4ijp2ya2g2drZ home]# bg 5
[5]+ ./test.sh &
[root@iZm5ehzqow4ijp2ya2g2drZ home]# jobs
[5] Running ./test.sh

上述后,我们发现程序就为后台运行了

进程的通信方式与信号

进程之间的通信就是两个进程之间可以有一些消息进行交互,还有就是两个进程之间可以互相进行控制。进程通信有很多种的方式,比如管道,信号,这里我们主要学习信号

信号:终端用户通过快捷键或者命令来输入信号,通过信号的机制可以让程序停止运行,经常使用的有 CTRL + C、kill等

kill命令

我们可以使用kill命令的 -l 参数来查看我们系统支持的所有信号,示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[root@iZm5ehzqow4ijp2ya2g2drZ ~]# kill -l
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP
6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1
11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM
16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR
31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3
38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8
43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7
58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2
63) SIGRTMAX-1 64) SIGRTMAX

以上就是我们系统中所有的信号,平时我们使用的CTRL + C对应的就是2号信号,SIGINT

kill命令具体使用方法:kill [-信号编号] 进程ID

比如我们平时使用的更多的是 kill -9 9号命令,它是用于强制停止进程,直接杀掉,一般我们在生产中直接使用 kill 命令来结束程序,可以达到优雅下线的效果

守护进程

很多时候我们希望我们有些进程在系统启动的时候就启动,或者有些我们在终端启动的进程在关闭终端之后还继续运行,Linux提供了实现这种需求的方法,就是使用守护进程,英文叫 daemon,就是精灵的意思,守护进程实现的就是我们不需要使用终端就可以把进程启动起来,另外启动的时候它的输出也会打印出来,并且这个程序使用的目录是根目录,避免占用其他一些移动硬盘的目录,导致此移动硬盘无法卸载的情况

nohup启动进程

在讲守护进程之前我们先讲另外一个进程,叫nohup启动进程,以此来对比守护进程

nohup启动进程会使进程忽略掉 hangup 挂起信号,使用此进程我们可以实现守护进程的效果,比如关掉终端之后进程还可以继续运行,但它还是有一些不同,首先这里示例一下使用nohup进程的效果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 首先我们使用第一个终端然后运行 tail 进程
[root@iZm5ehzqow4ijp2ya2g2drZ ~]# tail -1000f /balyu/logs/platformrun.log
2019-10-19 01:02:12.606 [http-nio-80-exec-16] INFO com.sparrow.portal.IndexController - access index...
2019-10-19 01:18:06.548 [http-nio-80-exec-18] INFO com.sparrow.manage.monitor.AccessMonitor - 123.126.113.160
...

# 然后打开第二个终端查看此进程 这里是可以查看到的
[root@iZm5ehzqow4ijp2ya2g2drZ ~]# ps -ef | grep tail
root 12218 12129 0 13:46 pts/2 00:00:00 tail -1000f /balyu/logs/platformrun.log
root 12237 12221 0 13:47 pts/3 00:00:00 grep tail

# 然后第三步是直接关闭终端,不退出tail直接关闭终端窗口
# 然后第四步我们继续到另一个终端查看此进程 -> 发现tail进程也不存在了
[root@iZm5ehzqow4ijp2ya2g2drZ ~]# ps -ef | grep tail
root 12241 12221 0 13:49 pts/3 00:00:00 grep tail

下面示例使用nohup来是进程在终端关闭后继续运行

1
2
3
4
5
6
7
8
9
10
11
12
13
# 第一步使用nohup启动tail进程,启动后提示将此进程的输出比如tail的查看内容输出放在了 nohup.out 文件下
[root@iZm5ehzqow4ijp2ya2g2drZ ~]# nohup tail - 100f /balyu/logs/platformrun.log
nohup: ignoring input and appending output to `nohup.out'

# 第二步启动另外一个终端查看此进程,这里我们查看到此进程的父进程是 pts/3
[root@iZm5ehzqow4ijp2ya2g2drZ ~]# ps -ef | grep tail
root 12251 12221 0 13:54 pts/3 00:00:00 tail -100f /balyu/logs/platformrun.log
root 12270 12254 0 13:55 pts/2 00:00:00 grep tail

# 第三步关闭此终端,然后使用另一个终端查看tail进程,我们发现进程还在存活,但是父进程变成了?,这是因为我们的进程在终端关闭之后此进程就成了孤儿进程,孤儿进程一定要被其它进程所收留,那么这里它就被 1 号进程所收留,这里显示了一个 ?,但其实是 1 号进程,init进程
[root@iZm5ehzqow4ijp2ya2g2drZ ~]# ps -ef | grep tail
root 12251 1 0 13:54 ? 00:00:00 tail -100f /balyu/logs/platformrun.log
root 12272 12254 0 13:56 pts/2 00:00:00 grep tail

以上就是nohup的使用示例,这里我们发现虽然可以将进程一直运行,但是启动程序的时候还是要通过终端启动,还有一个特点就是我们的进程输出会放在我们执行命令的当前文件夹下的nohup.out文件,它会占用我们当前磁盘的空间,name我们可不可以像windows一样,设置开机自启动呢?并且有一个合理的日志文件或者输出内容的文件所在的位置呢?请看下面的内容

screen命令

Screen是一款由GNU计划开发的用于命令行终端切换的自由软件。用户可以通过该软件同时连接多个本地或远程的命令行会话,并在其间自由切换。GNU Screen可以看作是窗口管理器的命令行界面版本。它提供了统一的管理多个会话的界面和相应的功能

在Screen环境下,所有的会话都独立的运行,并拥有各自的编号、输入、输出和窗口缓存。用户可以通过快捷键在不同的窗口下切换,并可以自由的重定向各个窗口的输入和输出

总的来说个人理解就是使用screen启动的程序我们在退出screen之后,程序还会继续运行,退出终端也会如此,所以直接将启动的程序作为了守护进程

使用方法:

  1. 使用 screen 命令直接进入screen环境

  2. 操作完成后或者启动程序完成后,使用 CTRL + A D,退出(detached)screen环境

  3. 我们可以使用 screen -ls 查看所有screen的会话

  4. 可以使用 screen -r sessionid 恢复会话,注意这里的sessionid是上述使用-ls查询出来的信息

注意:我们可以在screen模式下结束我们的进程,退出此环境使用 exit 退出此环境

以下是使用示例:

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# 1.首先使用screen命令进入此环境
[root@iZm5ehzqow4ijp2ya2g2drZ ~]# screen
-bash: screen: command not found

# 2.这里提示找不到这个命令,是因为我们没有安装,需要使用yum命令进行安装
[root@iZm5ehzqow4ijp2ya2g2drZ ~]# yum install screen
Loaded plugins: fastestmirror
Setting up Install Process
...
Installed:
screen.x86_64 0:4.0.3-19.el6

Complete!

# 3.安装成功后再次使用此命令进入Screen环境,我们发现直接就进入了此环境,并没有任何提示和不一样的地方
[root@iZm5ehzqow4ijp2ya2g2drZ ~]# screen

[root@iZm5ehzqow4ijp2ya2g2drZ ~]#

# 4.再此环境下执行命令,还是之前使用的tail命令来让它后台运行
[root@iZm5ehzqow4ijp2ya2g2drZ ~]# tail -1000f /balyu/logs/platformrun.log
2019-10-26 00:15:58.351 [http-nio-80-exec-9] INFO com.sparrow.portal.IndexController - access index...
2019-10-26 00:51:58.660 [http-nio-80-exec-7] ERROR org.apache.catalina.core.ContainerBase.[Tomcat].[localhost] - Exception Processing ErrorPage[errorCode=0, location=/error]
org.apache.catalina.connector.ClientAbortException: java.io.IOException: Connection reset by peer

# 5.使用另外一个客户端,查看此启动的进程,我们发现实可以查询到的
[root@iZm5ehzqow4ijp2ya2g2drZ ~]# ps -ef | grep tail
root 20513 20484 0 12:02 pts/1 00:00:00 tail -1000f /balyu/logs/platformrun.log
root 20532 20516 0 12:04 pts/3 00:00:00 grep tail

# 6.我们使用CTRL + A D退出screen环境,退出后发现终端并没有什么变化
[root@iZm5ehzqow4ijp2ya2g2drZ ~]# screen
[detached]
[root@iZm5ehzqow4ijp2ya2g2drZ ~]#

# 7.我们再次用第二个客户端查看在screen环境中启动的tail进程发现是可以查询到的,即使将第一个终端直接关闭掉,也是可以查询到此进程
[root@iZm5ehzqow4ijp2ya2g2drZ ~]# ps -ef | grep tail
root 20513 20484 0 12:02 pts/1 00:00:00 tail -1000f /balyu/logs/platformrun.log
root 20538 20516 0 12:09 pts/3 00:00:00 grep tail

# 8.使用第二个终端查询当前系统上运行的screen环境, screen -ls 命令,查询发现启动的有一个,并且sessionid是20483
[root@iZm5ehzqow4ijp2ya2g2drZ ~]# screen -ls
There is a screen on:
20483.pts-0.iZm5ehzqow4ijp2ya2g2drZ (Detached)
1 Socket in /var/run/screen/S-root.

# 9.使用 screen -r sessionid恢复此screen环境,发现是恢复了的
[root@iZm5ehzqow4ijp2ya2g2drZ ~]# screen -r 20483

at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:726)
at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:471)
...

# 10.使用CTRL + C 退出此环境下前台运行的程序(tail 程序),然后使用exit退出screen环境
... 这里不做演示

# 11.再次使用screen -ls 查询运行的screen环境,发现已经查询不到了,因为我们已经退出了
[root@iZm5ehzqow4ijp2ya2g2drZ ~]# screen -ls
No Sockets found in /var/run/screen/S-root.

系统日志

这里只是一个补充说明,我们可以进入 /var/log 文件夹,这里有大量的日志文件,这些文件叫做系统日志,我们系统运行的状态都记录在这些文件中,重点关注以下文件就行:

  1. messages文件,系统的常规日志,也可以理解为当前系统运行实时产生的日志

  2. dmesg文件,内核日志信息,内核日志一般在我们启动系统的时候启动内核所打印出来的日志,一般我们在系统启动时可能查看的不够详细,这样我们就可以直接查看此文件来详细查看内核启动运行的一些日志信息

  3. secure文件,这个文件是我们系统的安全日志,此文件可以查看系统有没有产生一些安全的问题

  4. cron文件,这个日志是我们系统执行计划任务,定时任务等产生的日志,查看这种任务的日志可以在此文件中查看

服务管理工具

这里服务指的是提供常见功能的守护进程,是系统本身所提供的服务。服务管理工具说的是我们之前在网络管理和配置文件章节讲述过,有两种,CentOS7以前的版本是用的是service工具,之后默认使用的是systemctl工具,但是我们可以切换回service工具来管理

我们之前讲述过service的基本启动脚本在 /etc/init.d 文件夹中,这里有我们service管理工具所管理的所有服务,每个服务都有一个文件,此文件中便是服务的启动关闭重启等等的操作的命令脚本,这些脚本也可以我们自己来编写,就比如之前我们操作过的网卡服务,network文件中便有一堆关于操作网卡的脚本,每个操作我们可以理解为一个函数,函数中又具体的后台的逻辑。我们可以看到,service管理的服务脚本都很复杂。而systemctl管理工具基本的脚本在 /usr/lib/systemd/system 文件夹下,里面也是各种文件,文件所管理的就是服务,比如我们打开sshd.service文件,这个里面就是封装的sshd服务的一些操作脚本,我们明显可以看到这里的脚本比service管理的服务脚本要简单很多,这是因为脚本中具体的逻辑都已经有systemctl来管理了,不需要我们手动自己来写这些复杂的脚本,所有相对看着比较简单,我们在Linux系统的迭代中,会逐渐的将所有的service管理的服务都交给systenctl来管理。

之前我们说过service管理的服务都有级别,分为6个级别,这6个级别分别代表程序在哪个级别是启动的,在哪个级别的关闭的,我们可以通过service提供的chkconfig命令来查看及修改服务在各种级别运行的状态,而systemctl管理工具不是用过数字来代表启动级别了,而是直接通过英语单词来代表

systemctl管理工具怎么操作服务,我们列举一下常见的操作:

start、stop、restart、reload、enable、disable、status

使用的方法就是:systemctl 操作命令 服务名称,例如:systemctl start sshd.service

具体有哪些服务呢?我们可以直接查看 /usr/lib/systemd/system 文件夹,里面的内容中有很多扩展名为 .service.target 的文件,.service的文件就是我们管理的服务,我们就可以通过systemctl命令来操作这些服务,这些.target的文件,表示的就是服务表示的就是不同的级别,runleavel0.target 到 runleavel6.target 就表示我们之前描述的 0 - 6 的系统级别,我们可以通过命令 ls -l runleavel*.target 来查看这些文件的具体映射,这些查看出来的文件就映射到了具体的英文单词表示的级别

我们还可以通过 systemctl get-default 来查看我们当前系统的默认级别,字符级别还是图形界面级别。还可以通过 systemctl set-default 级别英文单词表示 来修改我们设置的默认级别,这样在下次启动系统的时候就切换了默认的级别,例如: systemctl set-default multy-user.target 就将默认的启动级别就切换成多用户的启动级别了,也就是字符界面级别

以上具体可以查看 网络管理和配置文件 章节

最后更新: 2019年11月02日 17:51

原始链接: https://jjw-story.github.io/2019/10/06/进程管理/

× 请我吃糖~
打赏二维码