命令:进程和服务管理

一:进程和服务管理

1.1 进程的概念

进程的概念:

  • 正在执行的程序
  • 正在计算机上执行的程序实例
  • 能分配处理器并由处理器执行的实体

进程的两个基本元素是,程序代码和代码相关联的数据集。进程是一种动态描述,但不代表所有的进程都在运行,这就可以引入“进程状态”。

# 其它了解概念知识:
程序:存放代码的文件=》静态
进程:程序的运行过程=》动态       # 同一个程序可能会有多个进程
父进程:程序运行时产生的第一个进程
子进程:由父进程衍生fork()出来的进程       #  如果父进程终止,子进程也会随之被终止
孤儿进程:父进程终止,子进程没有被回收      #  孤儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工作。 
僵尸进程:子进程退出,但是没有被父进程进行状态收集,子进程的描述符仍然保存载系统中。

孤儿进程和僵尸进程产生的原因:
归根结底还是Unix操作系统提供了一种这样的机制:让父进程可以知道子进程结束时的状态信息。
如果没有这种机制,一个子进程结束,就把他的所有资源和信息全部释放掉,那父进程就无法获得子进程结束时的状态信息了,对吧?所以子进程结束的时候会留下一个数据结构,用这个数据结构存储子进程结束时的信息,直到父进程调用wait或者waitpid的时候才释放。

那就有下面的情况发生:
一、如果父进程一直比较忙,或者因为其他原因没有去wait/waitpid子进程结束时候留下的状态信息,那这些已经结束的线程遗留的数据结构就无从清理,也就产生了所谓的僵尸进程,因为数据结构里包含pid等信息,操作系统的pid是有限的,因此僵尸进程是有害的。
二、如果父进程先于子进程结束,那子进程无父进程了,如果之后子进程也结束,谁去释放他遗留下来的数据结构呢?这个无父进程的子进程就叫孤儿进程,他将会被init进程(pid=1)托管,之后此子进程结束的话,他的遗留数据结构将会被init进程去wait/waitpid释放(这里我产生了一个疑问,希望可以和大家讨论一下,我们unix设计这种机制的初衷是为了让父进程可以知道子进程结束时的状态信息对吧,那父进程都挂掉了,子进程其实也无需遗留状态信息了,那操作系统是否可以这样设置:将孤儿进程交给init进程托管 改为:孤儿进程结束时,直接释放所有信息,包括其遗留数据结构)。

1.2 进程的状态

进程在内存中因策略或调度需求会处于各种状态:

R 可执行状态

# running又称运行状态,只有在运行状态的进程才有可能在CPU上运行,注意是可能,并不意味着进程一定在运行中。同一时刻可能有多个进程处在可执行状态,这些进程的PCB(进程控制块)被放入对应CPU的可执行队列中。然后进程调度器从各个可执行队列中分别选择一个进程在CPU上运行。另外如果计算机只有一个处理器,那么一次最多只有一个进程处于这种状态。

S 可中断睡眠

# sleeping 处在这个状态意味着进程在等待事件完成。这些进程的PCB(task_struct结构)被放入对应时间的等待队列中。然后等待的事件发生时,对应的进程将被唤醒。(io状态,而命令sleep是模拟睡眠达到静止)

D 不可中断睡眠

# disk sleep 在这个状态的进程通常会等待IO的结束。这个状态与sleeping状态相似,处于睡眠状态,但是此刻进程是不可中断的,意思是不响应异步信号。另外你会发现处在D状态的进程kill -9竟然也杀不死。这就相当于我们怎么也叫不醒一个装睡的人。

T 暂停状态

# stopped 给进程发送一个SIGSTOP信号,进程就会响应信号进入T状态,除非该进程正处在D状态。再通过发送SIGCONT信号让进程继续运行。
kill -SIGSTOP  # 杀死-信号停止
kill -SIGCONT  # 杀死-信号控制

Z 僵死状态

# zombie 僵死状态是一个比较特殊的状态。进程在退出的过程中,处于TASK_DEAD状态。在这个退出过程中,进程占有的所有资源将被回收,除了task_struct结构(以及少数资源)以外。于是进程就只剩下task_struct这么个空壳,故称为僵尸。

X 死亡/退出状态

# dead 死亡状态是内核运⾏ kernel/exit.c ⾥的 do_exit() 函数返回的状态。这个状态只是⼀个返回状态,你不会在任务列表⾥看到这个状态。

1.3 进程状态切换

# 进程在运行中不断的改变运行状态
# 就绪状态:
当进程已分配到除cpu以外的所有必要资源,只要获得处理机便可立即执行,这时的进程状态称之为就绪状态。
# 执行状态:
当进程已获得处理机,其程序正在处理机上执行,此时的进程状态称为执行状态。
# 阻塞状态:
正在执行的进程,由于等待某个事件发生而无法执行时,便放弃处理机而处于阻塞状态。引起进程阻塞的事件可有多种,例如,等待I/O完成、申请缓冲区不能满足、等待信件(信号)等。

就绪–>执行
处在就绪状态的进程,当调度器为其分配了处理机后,就变成了执行状态。

执行–>就绪
执行状态的进程在其执行过程中,时间片跑完了不得不让出处理机,于是从执行变成就绪状态。

执行–>阻塞
正在执行的进程等待某种事件而无法继续执行时,便从执行状态变成阻塞状态。

阻塞–>就绪
处在阻塞状态的进程,如果等待的时间发生,则从阻塞状态转变成就绪状态。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dfDguUXJ-1616513570308)(D:\linux 总结笔记\图片\进程状态.png)]
在这里插入图片描述

1.4 查看进程

ps aux是常用组合,查看进程用户、PID、占用CPU百分比、占用内存百分比、状态、执行的命令等。

-a     # 显示一个终端的所有进程
-u     # 选择有效的用户id或者是用户名
-x     # 显示没有控制终端的进程,同时显示各个命令的具体路径。# 后台所有进程

示例:
在这里插入图片描述

USER	# 运行进程的用户  
PID     # 当前进程的id号
PPID    # 当前进程的父进程
%MEM    # 内存占用率  
VSZ     # 占用虚拟内存,单位:kb(killobytes) # 进程启动时默认向计算机申请的内存
         VSZ是指已分配的线性空间大小,这个大小通常并不等于程序实际用到的内存大小,产生这个的可能          性很多,比如内存映射,共享的动态库,或者向系统申请了更多的堆,都会扩展线性空间大小。
RSS  	# 占用实际内存,单位:kb(killobytes)
        RSZ是Resident Set Size,常驻内存大小,即进程实际占用的物理内存大小   
TTY     # 进程运行的终端
          ?: 后台运行(没有终端)
	      tty:使用系统终端
	      pts:使用虚拟终端
STAT	# 进程状态	 man ps (/STATE)			
          R 	运行
          S 	可中断睡眠 Sleep,即在睡眠的过程中可以接收信号唤醒=》执行的IO操作可以得到硬件设备的响应
          D		不可中断睡眠,即在睡眠的过程中不可以接收信号唤醒=》执行的IO操作得不到硬件设备的响应
          T 	停止的进程 
          Z 	僵尸进程
          X 	死掉的进程(几乎看不见,因为死了就立即回收了)     
# 以下几个是配合上面的使用
          < 	标注了<小于号代表优先级较高的进程
	      N  	N代表优先级较低的进程	 
          s  	包含子进程	  
	      +		+表示是前台的进程组    
	      l	  	小写字母l,代表以线程的方式运行,即多线程
          | 	管道符号代表多进程   
START	# 进程的启动时间
TIME    # 进程占用CPU的总时间
COMMAND # 进程文件,进程名[]号的代表内核态进程
          不带[]号的代表用户态进程
# top监控界面快捷键
-e      # 显示所有的进程
-f      # 格式化输出同时显示PPID
PPID    # 父进程ID        

Linux进程有两种睡眠状态:

# 1、Interruptible Sleep(可中断睡眠,在ps命令中显示“S”)
处在这种睡眠状态的进程是可以通过给它发送signal来唤醒的,比如发HUP信号给nginx的master进程可以让nginx重新加载配置文件而不需要重新启动nginx进程;
# 2、Uninterruptible Sleep(不可中断睡眠,在ps命令中显示“D”)
处在这种状态的进程不接受外来的任何signal,这也是为什么之前我无法用kill杀掉这些处于D状态的进程,无论是“kill”、“kill -9”、“kill -15”还是按 Ctrl+C 、Ctrl+Z 都无济于,因为它们压根儿就不受这些信号的支配。

# 解释
进程为什么会被置于D状态呢?处于uninterruptible sleep状态的进程通常是在等待IO,比如磁盘IO,网络IO,其他外设IO,如果进程正在等待的IO在较长的时间内都没有响应,那么就很会不幸地被ps看到了,同时也就意味着很有可能有IO出了问题,可能是外设本身出了故障,也可能是比如NFS挂载的远程文件系统已经不可访问了。

正是因为得不到IO的响应,进程才进入了uninterruptible sleep状态,所以要想使进程从uninterruptible sleep状态恢复,就得使进程等待的IO恢复,比如如果是因为从远程挂载的NFS卷不可访问导致进程进入uninterruptible sleep状态的,那么可以通过恢复该NFS卷的连接来使进程的IO请求得到满足,除此之外,要想干掉处在D状态进程就只能重启整个Linux系统了(恐怖的D状态)。

看到有人说如果要想杀掉D状态的进程,通常可以去杀掉它的父进程(通常是shell,我理解的这种情况是在shell下直接运行的该进程,之后该进 程转入了D状态),于是我就照做了,之后就出现了上面的状态:他们的父进程被杀掉了,但是他们的父进程PID都变成了1,也就是init进程,这下可如何是好?此时我这些D状态的进程已经影响到其他一些进程的运行,而已经无法访问的NFS卷又在段时间内无法恢复,那么,只好重新启动了。

# 强调
D与Z状态的进程都无法用kill -9杀死

1.5 查看进程树

[root@egon ~]# yum -y  install psmisc
[root@egon ~]# pstree
[root@egon ~]# pstree 104239

bash───bash───bash───bash───pstree

1.6 查看父进程ppid

[root@egon ~]# ps -ef | head -10
UID         PID   PPID  C STIME TTY          TIME CMD
root          1      0  0 1101 ?      00:00:07 /usr/lib/systemd/systemd --system --deserialize 20
root          2      0  0 1101 ?      00:00:00 [kthreadd]
root          4      2  0 1101 ?      00:00:00 [kworker/0:0H]
root          6      2  0 1101 ?      00:00:06 [ksoftirqd/0]
root          7      2  0 1101 ?      00:00:00 [migration/0]
root          8      2  0 1101 ?      00:00:00 [rcu_bh]
root          9      2  0 1101 ?      00:00:03 [rcu_sched]
root         10      2  0 1101 ?      00:00:00 [lru-add-drain]
root         11      2  0 1101 ?      00:00:01 [watchdog/0]

1.7 top动态查看

根据一定的频率去监控系统

在这里插入图片描述

# 二 显示信息解释
第一部分:系统整体统计信息
top - 22:24:56 up  7:11,  1 user,  load average: 0.00, 0.01, 0.05
up左边的代表当前的时间
up右边代表运行了多长时间
load average: 0.86, 0.56, 0.78	  CPU 1分钟,5分钟,15分钟平均负载
---------------------------------------------------------------------------------------------------------------------------------------- Tasks: 125 total,   1 running, 124 sleeping,   0 stopped,   0 zombie
total : 当前系统一共运行的是125个进程
running : 正在运行的是1个
sleeping : 124个处于睡眠状态
stopped : 停止运行的进程数
zombie  :僵尸进程数    
----------------------------------------------------------------------------------------------------------------------------------------
%Cpu0  :  0.0 us,  0.0 sy,  0.0 ni,100.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st    
us 用户态进程占用cpu时间的百分比
sys 内核态进程占用cpu时间的百分比
ni 代表优先被调度的进程占cpu时间的百分比
id cpu空闲的百分比
wa cpu等待io的百分比
hi 硬件中断,处理硬件中断所占用CPU的时间
si 软件中断,处理软件中断所占用CPU的时间
st 被偷走的cpu
linux中断:https://www.cnblogs.com/linhaifeng/articles/13916102.html
---------------------------------------------------------------------------------------------------------------------------------------- KiB Mem :  2027892 total,  1234180 free,   176352 used,   617360 buff/cache
total :系统总内存
free  :系统空闲内存
used  : 系统使用内存
buff/cache : 缓存使用内存
avail Mem :可用内存
----------------------------------------------------------------------------------------------------------------------------------------
第二部分:进程信息
PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND 

PID : 进程编号
USER : 启动进程的用户
PR : 优先级
NI :nice值
VIRT : 虚拟内存
RES  : 使用内存
SHR  : 共享内存
%CPU : cpu使用率
%MEM :内存使用率
TIME+ COMMAND :时间+命令
----------------------------------------------------------------------------------------------------------------------------------------
top 命令 VSZ,RSS,TTY,STAT, VIRT,RES,SHR,DATA的含义
====================================================
VIRT:virtual memory usage 虚拟内存
1、进程“需要的”虚拟内存大小,包括进程使用的库、代码、数据等
2、假如进程申请100m的内存,但实际只使用了10m,那么它会增长100m,而不是实际的使用量

RES:resident memory usage 常驻内存
1、进程当前使用的内存大小,但不包括swap out(当某进程向OS请求内存发现不足时,OS会把内存中暂时不用的数据交换出去,放在SWAP分区中,这个过程称为SWAP OUT。当某进程又需要这些数据且OS发现还有空闲物理内存时,又会把SWAP分区中的数据交换回物理内存中,这个过程称为SWAP IN)
2、包含其他进程的共享
3、如果申请100m的内存,实际使用10m,它只增长10m,与VIRT相反
4、关于库占用内存的情况,它只统计加载的库文件所占内存大小

SHR:shared memory 共享内存
1、除了自身进程的共享内存,也包括其他进程的共享内存
2、虽然进程只使用了几个共享库的函数,但它包含了整个共享库的大小
3、计算某个进程所占的物理内存大小公式:RES – SHR
4、swap out后,它将会降下来,因为内存充裕了,大家就没必要合租内存了

DATA
1、数据占用的内存。如果top没有显示,按f键、然后用空格选中DATA项目、然后按q则可以显示出来。
2、真正的该程序要求的数据空间,是真正在运行中要使用的。

top快捷键

# 三 top 运行中可以通过 top 的内部命令对进程的显示方式进行控制。内部命令如下:
在top监控界面按一下命令键:
1	显示所有CPU的负载
s   改变画面更新频率
M	按内存的使用排序
z	彩色
P	按CPU使用排序
l   关闭或开启第一部分第一行 top 信息的表示
不常用:
N	以PID的大小排序
R	对排序进行反转
f	自定义显示字段
h|? 帮助
<	向前
>	向后

top参数

-d : 设置top的刷新频率
# top -d 1  # 1秒刷新一次
-p :  设置查看的进程PID
# top -d 1 -p `pgrep nginx | head -1`  # 查看nginx最后一行的进程pid
-u :  查询指定用户的进程
# top -u oldboy
-n : 表示查询n次
# top -d 0.1 -u oldboy -n 20
# top -b -n 2 > top.txt  # 将2次top信息写入到文件

cpu加压工具 stress

# CPU加压工具
stress --cpu [需要加压的系统核心数] --timeout [加压的时间]

# CPU 性能加压工具
## 添加epel源(epel源主要用来安装红帽系列操作系统附加软件)
yum install stress -y

# CPU 性能分析工具
yum install sysstat -y

mpstat -P ALL 3   

# 进程性能分析⼯具
pidstat -u 1 5  

epel源下载

[epel]
name=Extra Packages for Enterprise Linux 7 - $basearch
baseurl=https://mirrors.tuna.tsinghua.edu.cn/epel/7/$basearch
#mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-7&arch=$basearch
failovermethod=priority
enabled=1
gpgcheck=0

[epel-debuginfo]
name=Extra Packages for Enterprise Linux 7 - $basearch - Debug
baseurl=https://mirrors.tuna.tsinghua.edu.cn/epel/7/$basearch/debug
#mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-debug-7&arch=$basearch
failovermethod=priority
enabled=0
gpgcheck=0

[epel-source]
name=Extra Packages for Enterprise Linux 7 - $basearch - Source
baseurl=https://mirrors.tuna.tsinghua.edu.cn/epel/7/SRPMS
#mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-source-7&arch=$basearch
failovermethod=priority
enabled=0
gpgcheck=0

二: 优先级设置

2.1 nice 优先级设置

# 可以在启动进程时用nice命令设置优先级,让命令以新的优先级执⾏
nice -n 优先级 进程
# nice -n -13 ls
优先级:
     普通用户0-19
     root用户-20-19
优先值越低,优先级越高
# 可通过

2.2 指定用户设定优先级renice

# 也可以对已运⾏的进程设置新的优先级
renice 优先级 pid

2.3 ps -l命令查看优先级

在这里插入图片描述

UID : 代表执⾏者的身份
PID : 代表这个进程的代号
PPID :代表这个进程是由哪个进程发展衍⽣⽽来的,亦即⽗进程的代号
PRI :代表这个进程可被执⾏的优先级,其值越⼩越早被执⾏
NI :代表这个进程的nice值
PRI即进程的优先级,此值越⼩进程的优先级别越⾼。⽽NI,也就是我们所要说的nice值(通过nice命令设置),其表示进程可被执⾏的优先级的修正数值。如前⾯所说,PRI值越⼩越快被执⾏,那么加⼊nice值后,将会使得PRIPRI(new)=PRI(old)+nice。
所以,nice命令设置的优先级不是程序最终的优先级,⽽只是优先级的修正数值。renice命令允许⽤户修改⼀个正在运⾏的进程的优先权。

三: linux系统信号

# 本信号在用户终端连接(正常或非正常)结束时发出,通常时在终端的控制进程结束时,通知同一个阶段内的各个作业,这时他们与控制终端不在关联。此外,对于与终端脱离关系的守护进程,这个信号⽤于通知它重新读取配置⽂件。(get能捕获SIGHUP信号,并忽略它,这样就算退出了Linux登录,wget也 能继续下载。)

3.1 kill 信号使用

kill -l # 列出所有⽀持的信号
格式:
kill -[信号名称/信号ID] pid
或:		kill -SIGINT  PID
或:		kill -INT     PID
或:		kill -2       PID 
或:kill 进程ID  # 默认15终止

遇到多个vim打开文件类的,可以用pkill -9 进程id/vim # 强制杀死
# 常用:
1) SIGHUP   重载	
2) SIGINT   中断信号 
            ctrl + c
	        ctrl + z        
9) SIGKILL   强制杀死   # 强制将进程杀死,并跟进程有关全部停止  # D与Z状态的进程都⽆法⽤kill -9杀死,信号不能被捕捉
15) SIGTERM  发出终止信号   # 优雅终止进程,通知它自己结束
17) SIGCHLD  停止
19) SIGSTOP  停止
20) SIGTSTP  将进程暂停
23) SIGURG   停止
18) SIGCONT  恢复
退出信号:ctrl + d

例:

# 1、在窗⼝1执⾏命令
[root@egon ~]# vim egon.txt
# 2、在窗⼝2查看vim的运⾏状态为:S+
[root@egon ~]# ps aux |grep [v]im
root 103231 1.5 0.2 149828 5460 pts/2 S+ 17:48 0:00 vim
egon.txt
# 3、在窗⼝1执⾏:ctrl+z,将进程放置到后台
[root@egon ~]# vim egon.txt
[4]+ 已停⽌ vim egon.txt
# 4、在窗⼝2查看vim的运⾏状态为:T [root@egon ~]# ps aux |grep [v]im
root 103231 0.3 0.2 149828 5460 pts/2 T 17:48 0:00 vimegon.txt

四:关于hup信号

当终端整体关闭,不时单纯的exit时,终端会受到linux hup的信号,然后终端在结束前会关闭其所有子进程。如果我们想让进程在后台一直运行,不要因为用户注销,网络断开,终端关闭而一起被干掉,那么我们有两种解决方案:

  • 让进程忽略linux hup信号
  • 让进程运行在新的会话里,从而成为不属于此进程的子进程,就不会在当前终端挂掉的情况下一起被带走

4.1 nohup 后台启动

针对⽅案1,我们可以使⽤nohup命令,nohup 的⽤途就是让提交的命令忽略 hangup 信号,该命令通

常与&符号⼀起使⽤.

# nohup 的使⽤是⼗分⽅便的,只需在要处理的命令前加上 nohup 即可,但是 nohup 命令会从终端解除进程的关联,进程会丢掉STDOUT,STDERR的链接。标准输出和标准错误缺省会被重定向到nohup.out ⽂件中。⼀般我们可在结尾加上"&"来将命令同时放⼊后台运⾏,也可⽤">filename2>&1"来更改缺省的重定向⽂件名。
nohup 执行的命令 &

在这里插入图片描述

在这里插入图片描述

3.3 setsid 开启了孤儿进程

针对⽅案1,我们还可以⽤setsid命令实现,原理与nohup是⼀样的,setid是直接将进程的⽗pid设置成1,

即让运⾏的进程归属于init的⼦进程,那么除⾮init结束,该⼦进程才会结束,当前进程所在的终端结束

后并不会影响进程的运⾏

setsid 执行的命令  # 也可以在后⾯加&符号
# 1、在终端2中执⾏命令
[root@egon ~]# setsid ping www.baidu.com # 也可以在后⾯加&符号
# 2、关闭终端2
# 3、在终端1中查看
[root@egon ~]# ps -ef |grep [p]ing
root 102335 1 0 17:53 ? 00:00:00 ping www.baidu.com

3.4 screen 开启一个子窗口

# 1、安装
[root@egon ~]# yum install screen -y
# 2、运⾏命令
⽅式⼀:开启⼀个窗⼝并⽤-S指定窗⼝名,也可以不指定
[root@egon ~]# screen -S egon_dsb
'''
Screen将创建⼀个执⾏shell的全屏窗⼝。你可以执⾏任意shell程序,就像在ssh窗⼝中那样。
在该窗⼝中键⼊exit则退出该窗⼝,如果此时,这是该screen会话的唯⼀窗⼝,该screen会话退
出,否则screen⾃动切换到前⼀个窗⼝。
'''
⽅式⼆:Screen命令后跟你要执⾏的程序
[root@egon ~]# screen vim test.txt
'''
Screen创建⼀个执⾏vim test.txt的单窗⼝会话,退出vim将退出该窗⼝/会话。
'''
# 3、原理分析
screen程序会帮我们管理运⾏的命令,退出screen,我们的命令还会继续运⾏,若关闭screen所在
的终端,则screen程序的ppid变为1,所以screen不会死掉,对应着它帮我们管理的命令也不会退
出# 终端连接的时screen,screen又创建了一个子窗口,终端断开,screen也会被一起断开,但是screen的子窗口还在运行。
测试略
# 4:重新连接会话
在终端1中运⾏
[root@egon ~]# screen
[root@egon ~]# n=1;while true;do echo $n;sleep 1;((n++));done
[root@egon ~]# 按下ctrl+a,然后再按下ctrl+d,注意要连贯,⼿别哆嗦, [root@egon ~]# 此时可以关闭整个终端,我们的程序并不会结束
打开⼀个新的终端
[root@egon ~]# screen -ls
There is a screen on:
 109125.pts-0.egon (Detached) 1 Socket in /var/run/screen/S-root. [root@egon ~]# screen -r 109125 # 会继续运⾏
[root@egon ~]#
注意:如果我们刚开始已经⽤screen -S xxx指定了名字,那么我们其实可以直接
screen -r xxx ,就⽆须去找进程id了
远程演示
# 在终端1: [root@egon ~]# screen -S egon_av
# 开启⼀个新的终端,在该终端执⾏的命令,终端1会同步显示
[root@egon ~]# screen -x egon_av

3.5 在子shell中提交任务

# 1、在终端2中执⾏命令
[root@egon ~]# (ping www.baidu.com &) # 提交的作业并不在作业列表中
# 2、关闭终端2
# 3、在终端1中查看
[root@egon ~]# ps -ef |grep [p]ing
root 102361 1 0 17:55 ? 00:00:00 ping www.baidu.com
 
可以看到新提交的进程的⽗ ID(PPID)为1(init 进程的 PID),并不是当前终端的进程 ID。
因此并不属于当前终端的⼦进程,从⽽也就不会受到当前终端的Linux HUP信号的影响了。

四:查看网络状态

4.1 查看各种网络状态

netstat      # 主要用来查询系统端口相关问题,等同于netstat -an
注: 要使用netstat需要安装yum install -y net-tools  
# lsof -i:22   # 指定查看22,可按窗口号查看是否有这个窗口
# route -n   # 查看ip网关状态
# du -sh /etc/  # 统计/etc/文件夹下所有的内容总共的大小  

[root@tianyun ~]# netstat -tnlp # 查看正在监听的,且使⽤tcp协议的进程,等同于netstat -tunalp/tunlp
-t tcp协议
-u udp协议
-l 监听
-p 打印进程的PID/Program name
-n 不反解,不将IP地址解析为主机名,不将端⼝号解析成对应的协议名(80 ---> http)

五:proc文件系统

查看硬盘df

df    # 所有硬盘
df -h # 硬盘容量
df -T # 硬盘类型

cpu查看 proc

/proc/cpuinfo

# du -sh /proc # 
lscup # 查看cpu的一些信息
cpuinfo  # 查看信息

查看内存 free

/proc/meminfo

free -m # 查看内存详细数据(meminfo)

total used free shared buff/cache available

总共 应用程序真正在用的内存 未分配自由的 共享 缓冲/缓存 剩余针对启用新程序

used= total-free-buff-cache

free -w  # 将数据写入内存(缓存)如果要释放数据需要先将数据执行写入内存 
释放:
echo 3 > /proc/sys/vm/drop_caches

查看内核

内核启动参数:/proc/cmdline

cmdl ine # 网卡配置

[root@localhost ~]# cat /proc/cmdline
BOOT_IMAGE=/vmlinuz-3.10.0-1127.13.1.el7.x86_64 root=UUID=84b5cfa6-b0dc- 4d7a-a8fd-0302f0eb2f04 ro rhgb quiet LANG=zh_CN.UTF-8 
[root@localhost ~]# uptime
17:42:40 up 1 day, 1:33, 2 users, load average: 0.00, 0.01, 0.05
-------------------------------------------------
注意:当我们卸载/proc后,下述命令都不可⽤
root@localhost ~]# umount /proc -l
-------------------------------------------------
free -m    # 查看内存buff/cache
free -wm   # 查看内存分开
uptime
lscpu
toop
-------------------------------------------------
# 重新挂载
[root@localhost ~]# mount -t proc proc /proc/
-t proc 指定⽂件系统的类型
proc ⽂件系统,虚拟⽂件系统
/proc 挂载点

六:后台管理进程

6.1 后台查看jobs

执行在后台原地睡眠后可在同一个窗口(换了不行)查看后台的运行
[root@localhost ~]# sleep 5000 & # 运⾏程序(时),让其在后台执⾏
[1] 31143
[root@localhost ~]# sleep 4000 # ^z,将前台的程序挂起(暂停)到后台
[root@localhost ~]# jobs # 中括号内的编号就是作业编号,%1代表作业1 [1]- 运⾏中 sleep 5000 & [2]+ 已停⽌ sleep 4000
[root@localhost ~]# bg %2 # 让作业2在后台运⾏
[2]+ sleep 4000 & [root@localhost ~]# fg %1 # 将作业1调回到前台
[root@localhost ~]# jobs
[2]+ 运⾏中 sleep 4000 & [root@localhost ~]# kill %2
nohup
加在⼀个命令的最前⾯,表示不挂断的运⾏命令

七:管道

7.1 管道的用法

**管道⽤于进程间通信,详细地说,管道操作符号 “|” ,主要⽤来连接左右两个命令, 将左侧的命令的标准输出, 交给右侧命令的标准输⼊ **。

PS: ⽆法传递标准错误输出⾄后者命令

#思路: 打印所有访问的过来的ip | 排序 | 去重 | 倒序排序 | 取前10
[root@egon ~]# awk '{print $1}' access.log |sort |uniq -c |sort -rn|head
12049 58.220.223.62
10856 112.64.171.98
1982 114.83.184.139
1662 117.136.66.10
1318 115.29.245.13
961 223.104.5.197
957 116.216.0.60
939 180.111.48.14
871 223.104.5.202
869 223.104.4.139

7.2 管道中的tee技术

tee       # 可将命令的输出即可以添加到文件也可以存在终端(类似>)
tee -a    # 追加(类似>>)
ifconfig | tee b.txt  # 将ifconfig执行的命令结果输出到文件和终端
----------------------------------------------
# 重定向与 tee 他们在使⽤过程中有什么区别?
# date > date.txt    # 直接将内容写⼊date.txt⽂件中
# date |tee date.txt # 命令执⾏会输出⾄屏幕,但会同时保存⼀份⾄date.txt⽂件中

7.3 参数传递xargs

让⼀些不⽀持管道的命令可以使⽤管道技术(可以理解为,不能进行处理的,如touch,find,rm,ls)

[root@egon ~]# which cat|xargs ls -l
[root@egon ~]# ls |xargs rm -fv
[root@egon ~]# ls |xargs cp -rvt /tmp/ -或-> ls | xargs -I {} cp -rv {}
/tmp/
[root@egon ~]# ls |xargs mv -t /tmp/ -或-> ls | xargs -I {} mv {} /tmp

八:孤儿进程

⽗进程先死掉,⽽它的⼀个或多个⼦进程还在运⾏,那么那些⼦进程将成为孤⼉进程。孤⼉进程将被
程号为1的顶级进程(init或systemd)所收养,并由顶级进程对它们完成状态收集⼯作。
进程就好像是⼀个⺠政局,专⻔负责处理孤⼉进程的善后⼯作。每当出现⼀个孤⼉进程的时候,内核就把孤⼉进程的⽗进程设置为顶级进程,⽽顶级进程会循环地wait()它的已经退出的⼦进程。这样,当⼀个孤⼉进程凄凉地结束了其⽣命周期的时候,顶级进程就会代表党和政府出⾯处理它的⼀切善后⼯作。因此孤⼉进程并不会有什么危害。

九:僵尸进程

冤魂 Z 是杀不死的,是因为它已经死了,否则怎么叫 Zombie(僵⼫)呢?冤魂不散,⾃然是⽣前有结未解之故。在UNIX/Linux中,每个进程都有⼀个⽗进程,进程号叫PID(Process ID),相应地,⽗进程号就叫PPID(Parent PID)。当进程死亡时,它会⾃动关闭已打开的⽂件,舍弃已占⽤的内存、交换空间等等系统资源,然后向其⽗进程返回⼀个退出状态值,报告死讯。如果程序有 bug,就会在这最后⼀步出问题。⼉⼦说我死了,⽼⼦却没听⻅,没有及时收棺⼊殓,⼉⼦便成了僵⼫......
#1、什么是僵⼫进程
操作系统负责管理进程我们的应⽤程序若想开启⼦进程,都是在向操作系统发送系统调⽤当⼀个⼦进程开启起来以后,它的运⾏与⽗进程是异步的,彼此互不影响,谁先死都不⼀定linux操作系统的设计规定:⽗进程应该具备随时获取⼦进程状态的能⼒如果⼦进程先于⽗进程运⾏完毕,此时若linux操作系统⽴刻把该⼦进程的所有资源全部释放掉,那么⽗进程来查看⼦进程状态时,会突然发现⾃⼰刚刚⽣了⼀个⼉⼦,但是⼉⼦没了!!!这就违背了linux操作系统的设计规定所以,linux系统出于好⼼,若⼦进程先于⽗进程运⾏完毕/死掉,那么linux系统在清理⼦进程的时候,会将⼦进程占⽤的重型资源都释放掉(⽐如占⽤的内存空间、cpu资源、打开的⽂件等),但是会保留⼀部分⼦进程的关键状态信息,⽐如进程号the process ID,退出状the termination status of the process,运⾏时间the amount of CPU time taken by the process等,此时⼦进程就相当于死了但是没死⼲净,因⽽得名"僵⼫进程",其实僵⼫进程是linux操作系统出于好⼼,为⽗进程准备的⼀些⼦进程的状态数据,专⻔供⽗进程查阅,也就是说"僵⼫进程"是linux系统的⼀种数据结构,所有的⼦进程结束后都会进⼊僵⼫进程的状态
# 2、那么问题来了,僵⼫进程残存的那些数据不需要回收吗???
当然需要回收了,但是僵⼫进程毕竟是linux系统出于好⼼,为⽗进程准备的数据,⾄于回收操作,应该是⽗进程觉得⾃⼰⽆需查看僵⼫进程的数据了,⽗进程觉得留着僵⼫进程的数据也没啥⽤了,然后由⽗进程发起⼀个系统调⽤wait / waitpid来通知linux操作系统说:哥们,谢谢你为我保存着这些僵⼫的⼦进程状态,我现在⽤不上他了,你可以把他们回收掉了。然后操作系统再清理掉僵⼫进程的残余状态,你看,两者配合的⾮常默契,但是,怕就怕在。。。
# 3、分三种情况讨论
1、linux系统⾃带的⼀些优秀的开源软件,这些软件在开启⼦进程时,⽗进程内部都会及时调⽤
wait/waitpid来通知操作系统回收僵⼫进程,所以,我们通常看不到优秀的开源软件堆积僵⼫进
程,因为很及时就回收了,与linux系统配合的很默契
2、⼀些⽔平良好的程序员开发的应⽤程序,这些程序员技术功底深厚,知道⽗进程要对⼦进程负责,会在⽗进程内考虑调⽤wait/waitpid来通知操作系统回收僵⼫进程,但是发起系统调⽤
wait/waitpid的时间可能慢了些,于是我们可以在linux系统中通过命令查看到僵⼫进程状态
[root@egon ~]# ps aux | grep [Z]+
3、⼀些垃圾程序员,技术⾮常垃圾,只知道开⼦进程,⽗进程也不结束,就在那傻不拉⼏地⼀直开⼦进程,也压根不知道啥叫僵⼫进程,⾄于wait/waitpid的系统调⽤更是没听说过,这个时候,就真的垃圾了,操作系统中会堆积很多僵⼫进程,此时我们的计算机会进⼊⼀个奇怪的现象,就是内存充
⾜、硬盘充⾜、cpu空闲,但是,启动新的软件就是⽆法启动起来,为啥,因为操作系统负责管理进程,每启动⼀个进程就会分配⼀个pid号,⽽pid号是有限的,正常情况下pid也⽤不完,但怕就怕堆积⼀堆僵⼫进程,他吃不了多少内存,但能吃⼀堆pid
# 4、如果清理僵⼫进程
针对情况3,只有⼀种解决⽅案,就是杀死⽗进程,那么僵⼫的⼦进程会被linux系统中pid为1的顶级进程(init或systemd)接管,顶级进程会定期发起系统调⽤wait/waitpid来通知操作系统清理僵⼫针对情况2,可以发送信号给⽗进程,通知它快点发起系统调⽤wait/waitpid来清理僵⼫的⼉⼦kill -CHLD ⽗进程PID
# 5、结语
僵⼫进程是linux系统出于好⼼设计的⼀种数据结构,⼀个⼦进程死掉后,相当于操作系统出于好⼼帮它的爸爸保存它的遗体,之说以会在某种场景下有害,是因为它的爸爸不靠谱,⼉⼦死了,也不及时收⼫(发起系统调⽤让操作系统收⼫)说⽩了,僵⼫进程本身⽆害,有害的是那些⽔平不⾜的程序员,他们总是喜欢写bug,好吧,如果你想看看垃圾程序员是如何写bug来堆积僵⼫进程的你可以看⼀下这篇博客
https://www.cnblogs.com/linhaifeng/articles/13567273.html
已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 1024 设计师:白松林 返回首页