一、进程的状态

1、命令查看

top
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
28961 root 20 0 43816 3148 4040 R 3.2 0.0 0:00.01 top
620 root 20 0 37280 33676 908 D 0.3 0.4 0:00.01 app
1 root 20 0 160072 9416 6752 S 0.0 0.1 0:37.64 systemd
1896 root 20 0 0 0 0 Z 0.0 0.0 0:00.00 devapp
2 root 20 0 0 0 0 S 0.0 0.0 0:00.10 kthreadd
4 root 0 -20 0 0 0 I 0.0 0.0 0:00.00 kworker/0:0H
6 root 0 -20 0 0 0 I 0.0 0.0 0:00.00 mm_percpu_wq
7 root 20 0 0 0 0 S 0.0 0.0 0:06.37 ksoftirqd/0

2、进程状态图解

向一个进程发送SIGSTOP 信号,它就会因响应这个信号变成暂停状态(Stopped);再向它发送 SIGCONT 信号,进程又会恢复运行(如果进程是终端里直接起动的,

则需要你用fg命令,回复到前台运行)

而当你的用的调试器调试一个进程是,在使用断点中断进程后,进程就会变成跟踪状态,这其实也就是一种特殊的暂停状态,只不过你可以用调试器
来跟踪并按需控制进程的运行

了解了这些,我们再回到今天的主题,先看不可终端状态,这其实是为了保证进程数据与硬件状态一直,并且增长情况下,不可终端状态在很短时间内会结束,

所以短时的不可终端进程我们一般可忽略

但如果系统或硬件发生了故障,进程可能会在不可中断状态保持很久,甚至导致系统中出现大量不可中断进程,这时,你就得注意下,系统时不时出现了I/O 等性能问题。

再看僵尸进程,这是多进程应用很容易碰到的问题,正常情况下,当一个进程创建了子进程后,它应该通过系统调用 wait() 或者 waitpid() 等待子进程结束,回收子进程的资源;
而子进程在结束时,会向它的父进程发送SIGCHLD 信号,所以,父进程还可以注册 SIGCHLD信号的处理函数,异步回收资源

如果父进程这么做,或是子进程执行太快,父进程还没有来得及处理子进程状态,子进程就已经提前退出,那这时的紫禁城就会变成僵尸进程,换句话说,父亲应该一直对儿子负责,善始善终,如果不作为或者跟不上、都会导致"问题少年"的出现

通常、僵尸进程持续的时间都比较短,在父进程回收它的资源后就会消亡;或者在父进程推出后,由init进程回收后也会消亡

一旦父进程没有处理子进程的种植,还一直保持运行状态,那么子进程就会一直处于僵尸状态,大量的僵尸进程会用尽PID进程号,
导致新进程不能创建,所以这种情况一定要避免

二、案例分析

1、运行案例应用

docker run --privileged --name=app -itd feisky/app:iowait

2、ps命令确认案例应用已正常启动

ps aux | grep /app
root 4009 0.0 0.0 4376 1008 pts/0 Ss+ 05:51 0:00 /app
root 4287 0.6 0.4 37280 33660 pts/0 D+ 05:54 0:00 /app
root 4288 0.6 0.4 37280 33668 pts/0 D+ 05:54 0:00 /app

1、s 和 + 是什么意思呢?

s 表示这个进程是一个会话的领导进程,而 + 表示前台进程组

这里又出现了两个新概念,进程组和会话,他们用来管理一组相互关联的进程,意思其实很好理解

2、什么是进程组?

进程组表示一组相互关联的进程,比如每个子进程都是父进程所在组的成员;而会话是只共享同一个控制终端的一个或多个进程组

3、什么是会话?

比如,我么通过SSH登录服务器,就会打开一个控制终端(TTY),这个控制终端就对应一个会话,而我我们在终端中运行的命令以及他们的子进程
就构成了一个个的进程组,其中,在后台运行的命令,构成后台进程组;在前台运行的命令,就构成前台进程组

3、top查看资源使用情况

# 按下数字 1 切换到所有 CPU 的使用情况,观察一会儿按 Ctrl+C 结束
$ top
top - 05:56:23 up 17 days, 16:45, 2 users, load average: 2.00, 1.68, 1.39
Tasks: 247 total, 1 running, 79 sleeping, 0 stopped, 115 zombie
%Cpu0 : 0.0 us, 0.7 sy, 0.0 ni, 38.9 id, 60.5 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu1 : 0.0 us, 0.7 sy, 0.0 ni, 4.7 id, 94.6 wa, 0.0 hi, 0.0 si, 0.0 st
... PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
4340 root 20 0 44676 4048 3432 R 0.3 0.0 0:00.05 top
4345 root 20 0 37280 33624 860 D 0.3 0.0 0:00.01 app
4344 root 20 0 37280 33624 860 D 0.3 0.4 0:00.01 app
1 root 20 0 160072 9416 6752 S 0.0 0.1 0:38.59 systemd
...

4、分析过程

从这里你能看出什么问题吗?逐行观察,别放过任何一个地方,忘了哪行参数意思的话,也要及时返回去复习

先看第一行平均负载,过去1、5、15分钟内的平均负载依次减小,说明平均负载正在升高,而1分钟内的平均负载已经达到了系统CPU的个数,说明系统可能已经有了性能瓶颈

Tasks 有1个正在运行的进程,但僵尸进程比较多,而且还在不停增加,说明有子进程在退出时没有没清理

CPU使用率:用户CPU和系统CPU都不高,但iowait分别是60.5%和94.6%好像有点不正常

每个进程的情况:CPU使用率最高的进程只有0.3%,看起来并不高;但是有两个进程处于D状态,它们可能在等待I/O,但光凭这里并不能确定是它们导致了 iowait 升高

我们把这四个问题在汇总一下,就可以得到很明确的两点:

第一点:iowait太高了,导致系统的平均负载生该,甚至达到系统CPU的个数

第二点:僵尸进程在不断增多,说明程序没能正确清理子进程的资源

三、遇到的问题及小结

1、用top命令观察,平均负载也不高,然后wa也很低,也没有看到D状态的进程

2、解决办法

老师说可能是案例里I/O线程还不够多,效果不明显,等着老师修改案例重新发镜像,再实验。
在和老师多次交流下,终于逼得老师发布一个把自己机器跑死的镜像,就可以了,结果和老师的温和了。

[root@luoahong ~]# docker run --privileged --name=app -itd feisky/app:iowait-new2
Unable to find image 'feisky/app:iowait-new2' locally
iowait-new2: Pulling from feisky/app
32802c0cfa4d: Already exists
da1315cffa03: Already exists
fa83472a3562: Already exists
f85999a86bef: Already exists
f69cb5280862: Pull complete
Digest: sha256:9fc8b013aff0bc2c1b1dc41a33989a8ddd4ed7da56f53f6559bbc76836041dc2
Status: Downloaded newer image for feisky/app:iowait-new2
00ed5564248127a98c467eb99f8b32d3dc3ebc5d7f47563d6617ccfd7348b10b
[root@luoahong ~]# ps aux | grep /app
root 11798 0.1 0.0 4368 380 pts/0 Ss+ 09:54 0:00 /app
root 11851 0.0 0.8 70040 65776 pts/0 R+ 09:55 0:00 /app
root 11852 0.0 0.8 70040 65776 pts/0 R+ 09:55 0:00 /app
root 11854 0.0 0.0 112708 980 pts/0 S+ 09:55 0:00 grep --color=auto /app

top截图

执行这个镜像,iowait打满,直接把我的微信给挤掉了,浏览器都打不开了,不过结果是好的。

3、小结

用我么最熟悉的ps或者top,可以直接查看进程的状态,这些状态包括运行(R)、空闲(I)、不可中断睡眠(D)、可中断睡眠(S)、僵尸(Z)以及暂停(T)等

其中,不可中断状态和僵尸状态,是我们今天学习的重点

不可中断状态:表示进程正在跟硬件交互,为了保护进程数据和硬件的一致性,系统不允许其他进程或中断打断这个进程。进程长时间处于不可中断状态,通常标识系统有I/O 性能问题

僵尸进程表示进程已经退出,但它的父进程还没有回收子进程占用资源。短暂的僵尸状态我们通常不必理会,但进程长时间属于僵尸状态,

就应该注意了,可能有应用程序没有正常处理子进程退出

Linux性能优化实战学习笔记:第七讲的更多相关文章

  1. Linux性能优化实战学习笔记:第四十一讲

    一.上节回顾 上一节,我们探究了网络延迟增大问题的分析方法,并通过一个案例,掌握了如何用hping3.tcpdump.Wireshark.strace 等工具,来排查和定位问题的根源. 简单回顾一下, ...

  2. Linux性能优化实战学习笔记:第九讲

    一.中断的魅力 1.中断在生活的魅力 比如你订了一份外卖,但是不确定外卖什么时候送到,也没有别的方法了解外卖的进度,但是,配送员送外卖是不等人的,到了你这儿没人取的话,就直接走人了.所以你指能苦苦等着 ...

  3. Linux性能优化实战学习笔记:第三十六讲

    一.上节总结回顾 上一节,我们回顾了经典的 C10K 和 C1000K 问题.简单回顾一下,C10K 是指如何单机同时处理 1 万个请求(并发连接 1 万)的问题,而 C1000K 则是单机支持处理 ...

  4. Linux性能优化实战学习笔记:第四十三讲

    一.上节回顾 上一节,我们了解了 NAT(网络地址转换)的原理,学会了如何排查 NAT 带来的性能问题,最后还总结了 NAT 性能优化的基本思路.我先带你简单回顾一下. NAT 基于 Linux 内核 ...

  5. Linux性能优化实战学习笔记:第四十五讲

    一.上节回顾 专栏更新至今,四大基础模块的最后一个模块——网络篇,我们就已经学完了.很开心你还没有掉队,仍然在积极学习思考和实践操作,热情地留言和互动.还有不少同学分享了在实际生产环境中,碰到各种性能 ...

  6. Linux性能优化实战学习笔记:第五十二讲

    一.上节回顾 上一节,我们一起学习了怎么使用动态追踪来观察应用程序和内核的行为.先简单来回顾一下.所谓动态追踪,就是在系统或者应用程序还在正常运行的时候,通过内核中提供的探针,来动态追踪它们的行为,从 ...

  7. Linux性能优化实战学习笔记:第五十五讲

    一.上节回顾 上一节,我们一起学习了,应用程序监控的基本思路,先简单回顾一下.应用程序的监控,可以分为指标监控和日志监控两大块. 指标监控,主要是对一定时间段内的性能指标进行测量,然后再通过时间序列的 ...

  8. Linux性能优化实战学习笔记:第三十一讲

    一.上节回顾 上一节,我们一起回顾了常见的文件系统和磁盘 I/O 性能指标,梳理了核心的 I/O 性能观测工具,最后还总结了快速分析 I/O 性能问题的思路. 虽然 I/O 的性能指标很多,相应的性能 ...

  9. Linux性能优化实战学习笔记:第三十二讲

    一.上节总结 专栏更新至今,四大基础模块的第三个模块——文件系统和磁盘 I/O 篇,我们就已经学完了.很开心你还没有掉队,仍然在积极学习思考和实践操作,并且热情地留言与讨论. 今天是性能优化的第四期. ...

  10. Linux性能优化实战学习笔记:第四十四讲

    一.上节回顾 上一节,我们学了网络性能优化的几个思路,我先带你简单复习一下. 在优化网络的性能时,你可以结合 Linux 系统的网络协议栈和网络收发流程,然后从应用程序.套接字.传输层.网络层再到链路 ...

随机推荐

  1. Debug 路漫漫-13:Python: pandas IndexError: single positional indexer is out-of-bounds

    在数据预处理过程中,出现:IndexError: single positional indexer is out-of-bounds 原因是在使用 Pandas 读取 dataframe 的时候,分 ...

  2. WPF中绘图(含调用GDI+)

    private void DrawStuff() { // //if (buffer == null) //{ // buffer = new RenderTargetBitmap((int)Back ...

  3. IOS开发实战-Xcode创建HelloWorld项目

    一.创建工程打开Xcode开发工具,在Welcome界面选择”Create a new Xcode project”选项 在选择模板窗口,选择”Single View Application” 确定模 ...

  4. Java基础—内部类

    在Java语言中,可以把一个类定义到另一个类的内部,在类里面的这个类就叫作内部类,外面的类叫作外部类.在这种情况下,这个内部类可以被看成外部类的是一个成员(与类的属性和方法类似).还有一种类被称为顶层 ...

  5. 在 Docker 中已运行的 container 如何修改 run 时的 env

    https://www.cnblogs.com/xiaouisme/p/9837221.html 首先不推荐这样做,如需修改配置,应删掉重新部署. 其次,可以进行如下操作(未测试,不知道仅重启 con ...

  6. leetcode - 括号字符串是否有效

    括号字符串是否有效 给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效. 有效字符串需满足: 左括号必须用相同类型的右括号闭合. 左括号必须以正确的顺序闭合. ...

  7. [b0014] HDFS 常用JAVA 操作实战

    目的: 学习用java进行的常用hdfs操作 参考: [b0002] Hadoop HDFS cmd常用命令练手 环境: hadoop2.6.4 win7 下的eclipse环境调试已经配置好,参考前 ...

  8. fetch的常见问题及其解决办法

    摘要: 玩转fetch. 作者:wonyun 原文:fetch使用的常见问题及其解决办法 Fundebug经授权转载,版权归原作者所有. 首先声明一下,本文不是要讲解fetch的具体用法,不清楚的可以 ...

  9. Swagger从入门到放弃

    如何编写基于OpenAPI规范的API文档 简介 Swagger Swagger是一个简单但功能强大的API表达工具.支持的语言种类繁多 使用Swagger生成API,我们可以得到交互式文档,自动生成 ...

  10. 如何解决问题:程序无法正常启动(0xc0000022)

    如何解决问题:程序无法正常启动(0xc0000022) 下文是由NeoSmart技术,通过全球网络上的工程师开发者和技术人员一起收集起来的信息,进行汇总并编辑而成的. 错误现象 该错误一般会通过警告, ...