进程状态:就绪/运行/阻塞
Linux下进程状态:
- R运行状态(running) : 并不意味着进程一定在运行中,它表明进程要么是在运行中要么在运行队列里。(就绪/运行) 只有运行状态的进程才会被操作系统调度在cpu上运行
- S可中断休眠状态(sleeping) :当前的阻塞能够被中断唤醒
- D不可中断休眠状态(Disk sleep) :当前的阻塞不能够被中断唤醒,等待条件满足自己醒来
- T停止状态(stopped) :可以通过发送 SIGSTOP 信号使进程停止运行,被暂停的进程可以通过发送 SIGCONT 信号使进程继续运行
- Z僵死状态(dead) :进程已经退出了,但是资源没有完全被释放的一种状态(这是一种等待后续处理的状态)
进程状态查看
ps axj / ps aux 命令
一般用第一个
查看最多创建进程数量
ulimit -a
-u: processes 1392
我的Mac最多创建1392个
Z(zombie)-僵尸进程
处于僵死态的进程(进程已经退出,但是资源没有完全释放)
僵尸进程的产生原因:
- 子进程退出并且父进程没有读取到子进程退出的返回代码时就会产生僵死(尸)进程
- 僵死进程会以终止状态保持在进程表中,并且会一直在等待父进程读取退出状态代码。
- 所以,只要子进程退出,父进程还在运行,但父进程没有读取子进程状态,子进程进入Z状态
僵尸进程的危害
资源泄露 :一个用户所能创建的进程数量是有限的,并且资源没有完全回收会占据内存资源
处理方法:
- 进程等待(父进程等待子进程退出,获取退出返回值,释放子进程资源)
- 退出父进程 (父进程退出,子进程保存退出原因就没有意义了因此也就被释放了)
思考题
- 子进程保存自身的退出原因,怎么保存,用什么形式保存?
(在自身上保存)进程就是pcb,进程的退出原因实际上是在pcb里面保存,以数据的形式来保存
- 僵尸进程资源泄漏,这个资源是指什么?
一个是进程的数量资源,一个是进程本身所占的内存资源
- 为什么要创建一个子进程?
子进程干的事情跟父进程是一样的,创建子进程可以分摊父进程的工作,提高效率
孤儿进程
父进程先于子进程退出,子进程则成为孤儿进程,运行在系统后台,并且这个孤儿进程的父进程成为1号进程。
孤儿进程是不会成为僵尸进程的,因为1号进程随时关注子进程的退出。(特殊的孤儿进程,脱离终端,会话影响。运行在后台)
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main() {
pid_t id = fork();
if(id < 0){
perror("fork");
return 1;
}
else if(id == 0){
printf("I am child, pid : %d\n", getpid());
sleep(10);
}
else{
printf("I am parent, pid: %d\n", getpid());
sleep(3);
exit(0);
}
return 0;
}
Mac终端下进程图:
守护进程/精灵进程:
是一种特殊的孤儿进程,父进程是1号进程,运行在后台,与终端以及登陆会话脱离关系,不再受影响。
守护进程通常是一种运行在系统后台的批处理程序(默默的做一些循环往复的事情)
如有不同见解,欢迎留言讨论~~