进程状态
进程状态:就绪/运行/阻塞
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个
linux的 0号进程 和 1 号进程
Linux下有3个特殊的进程,idle进程(PID = 0), init进程(PID = 1)和kthreadd(PID = 2)
- idle进程由系统自动创建, 运行在内核态
idle进程其pid=0,其前身是系统创建的第一个进程,也是唯一一个没有通过fork或者kernel_thread产生的进程。完成加载系统后,演变为进程调度、交换
- init进程由idle通过kernel_thread创建,在内核空间完成初始化后, 加载init程序, 并最终用户空间
由0进程创建,完成系统的初始化. 是系统中所有其它用户进程的祖先进程。
Linux中的所有进程都是有init进程创建并运行的。首先Linux内核启动,然后在用户空间中启动init进程,再启动其他系统进程。在系统启动完成完成后,init将变为守护进程监视系统其他进程。
- kthreadd进程由idle通过kernel_thread创建,并始终运行在内核空间, 负责所有内核线程的调度和管理
它的任务就是管理和调度其他内核线程kernel_thread, 会循环执行一个kthread的函数,该函数的作用就是运行kthread_create_list全局链表中维护的kthread, 当我们调用kernel_thread创建的内核线程会被加入到此链表中,因此所有的内核线程都是直接或者间接的以kthreadd为父进程
Z(zombie)-僵尸进程
处于僵死态的进程(进程已经退出,但是资源没有完全释放)
僵尸进程的产生原因:
- 子进程退出并且父进程没有读取到子进程退出的返回代码时就会产生僵死(尸)进程
- 僵死进程会以终止状态保持在进程表中,并且会一直在等待父进程读取退出状态代码。
- 所以,只要子进程退出,父进程还在运行,但父进程没有读取子进程状态,子进程进入Z状态
僵尸进程的危害
资源泄露 :一个用户所能创建的进程数量是有限的,并且资源没有完全回收会占据内存资源
处理方法:
- 进程等待(父进程等待子进程退出,获取退出返回值,释放子进程资源)
- 退出父进程 (父进程退出,子进程保存退出原因就没有意义了因此也就被释放了)
思考题
- 子进程保存自身的退出原因,怎么保存,用什么形式保存?
(在自身上保存)进程就是pcb,进程的退出原因实际上是在pcb里面保存,以数据的形式来保存
- 僵尸进程资源泄漏,这个资源是指什么?
一个是进程的数量资源,一个是进程本身所占的内存资源
- 为什么要创建一个子进程?
子进程干的事情跟父进程是一样的,创建子进程可以分摊父进程的工作,提高效率
孤儿进程
父进程先于子进程退出,子进程则成为孤儿进程,运行在系统后台,并且这个孤儿进程的父进程成为1号进程(init进程)。
孤儿进程是不会成为僵尸进程的,因为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号进程,运行在后台,与终端以及登陆会话脱离关系,不再受影响。
守护进程通常是一种运行在系统后台的批处理程序(默默的做一些循环往复的事情)
知识点习题
- 关于子进程和父进程的说法,下面哪一个是正确的?()
A. 一个父进程可以创建若干个子进程,一个子进程可以从属于若干个父进程
B. 父进程被撤销时,其所有子进程也被相应撤消
C. 子进程被撤销时,其从属的父进程也被撤销
D. 一个进程可以没有父进程或子进程
正确答案: D
答案解析:
1、孤儿进程
如果父进程先退出,子进程还没退出那么子进程将被托孤给init进程,这是子进程的父进程就是init进程(1号进程)
init进程没有父进程.(因为它就不是通过fork的方式产生的)
2、僵尸进程
进程终止后进入僵死状态(zombie),等待告知父进程自己终止,后才能完全消失.但是如果一个进程已经终止了,但是其父进程还没有获取其状态,那么这个进程就称之为僵尸进程.僵尸进程还会消耗一定的系统资源,并且还保留一些概要信息供父进程查询子进程的状态可以提供父进程想要的信息.一旦父进程得到想要的信息,僵尸进程就会结束.
- 下列关于进程和线程的描述,正确的是:
A. 进程不能直接从运行态到就绪态
B. 同一进程的线程可以资源共享
C. 同一进程的线程共享栈段
D. 进程是 CPU 调度的基本单位
正确答案: B
答案解析:
- 运行状态—>就绪状态:1)处于运行状态的进程时间片用完 2)当有更高优先级的进程就绪时
- 同一进程的线程的栈是私有的
- 进程是分配资源的基本单位
如有不同见解,欢迎留言讨论~~