Linux 进程状态
进程状态
top里面S列表示进程状态。
R |
正在运行或者等待运行(Running或Runnable),进程在CPU的就绪队列中。 |
D |
硬件交互导致的不可中断睡眠状态(Uninterruptible Sleep),进程正在与硬件交互。 |
Z |
僵尸进程(Zombie),虽然进程已经结束,但是父进程没有回收它的资源。父进程回收它的资源后会消亡;或者父进程退出后,init进程回收后也会消亡。 |
S |
可中断睡眠状态(Interruptible Sleep),进程因等待而挂起,唤醒后进入R状态。 |
I |
不可中断睡眠的空闲状态(Idle)。D状态进程会使平均负载升高,I状态进程不会。 |
T |
停止状态(stopped),不响应请求,发送SIGSTOP或者SIGTSTP信号来停止进程,发送SIGCONT信号让进程继续运行。其中,SIGSTOP和SIGTSTP信号区别在于,SIGSTOP信号不能捕获。 kill -19暂停进程,kill -18进程继续执行。 |
不可中断进程和僵尸进程案例
代码路径是https://github.com/feiskyer/linux-perf-examples/tree/master/high-iowait-process。
cd linux-perf-examples/high-iowait-process
构建镜像:make build
本地机器:docker run --privileged --name=app -itd feisky/app:iowait
执行top
根据Tasks这一行,有4个正在运行的进程,220个僵尸进程,而且僵尸进程的数量还在不断增加,说明有子进程退出时父进程没清理对应的资源。
通过ps aux | grep Z来寻找僵尸进程。
通过pstree -aps | grep 3381来寻找僵尸进程的父进程。
确认app应用代码是否存在问题,找到子进程的创建和清理位置
int status = 0; for (;;) { for (int i = 0; i < 2; i++) { if(fork()== 0) { sub_process(); } } sleep(5); } while(wait(&status)>0);
wait函数等待子进程结束没被调用到,把它挪到for循环里面。
int i = 0; for (;;) { for (i = 0; i < 2; i++) { if (fork() == 0) { sub_process(disk, buffer_size, buffer_count); } } while (wait(&status) > 0); sleep(5); }
子进程结束运行后,如果父进程没有调用wait或者waitpid来获取子进程的状态,内核无法释放内存中的子进程PCB,那么子进程成为僵尸进程。
fork出来的子进程和父进程同名,prctl设置的进程名只有在子进程死后或者变成僵尸进程时才显示。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统