进程的状态信息在task_struct中,进程状态方便操作系统快速判断进程,完成特定的功能,比如调度。进程状态本质是一种分类。
R运行状态并不意味着进程一定在运行中,它表明进程要么在运行,要么在运行队列。
当我们做某种任务时,任务条件不具备,需要进程进行某种等待,分为S,D。(所以千万不要认定进程只会等待CPU的资源,要区分睡眠状态和运行状态~~)
S睡眠状态(sleeping)->可中断睡眠(interruptible sleep),可以被杀掉!
D磁盘休眠状态(Disk sleep)->不可中断睡眠(uninterruptible sleep),不可以被杀掉,操作系统也不行!
开头提到,进程在运行的时候,可能会根据运行的需要,回放在不同的队列里,在不同队列,进程所处的状态不同。
在等待队列:
如果把运行状态的PCB放进等待队列,叫做 挂起等待(阻塞),反之把PCB从等待队列放到运行队列,叫做唤醒队列。
举个例子:S
+
表示前台运行;S状态可以通过ctrl+c终止。
而进程如果处于D状态,不可以被杀掉,比如,往磁盘写入1G的数据时,需要进程等待,这时的等待时D状态(深度睡眠)。
stopped
可以通过发送SIGSTOP信号给进程,停止(T)进程,被暂停的进程可以通过发送SIGCONT信号让进程继续运行。但此时进程不能通过ctrl+c终止了(kill -9 PID)
命令kill -l
查看:
tracing stop
dead
进程死亡需要回收进程资源,包括进程相关的内核数据结构,和代码、数据。
zombie,正常的死亡流程是Z—>X
**思考:**为什么会有僵尸进程?
这个过程就类似与案发现场,需要警察先封存现场,尸检完后再拉去火葬场(bushi,也就是先辨别退出的死亡原因,保存进程退出的信息,数据在PCB中。
如果没人检测或者回收进程,该进程就进入Z,又该如何检测?
前台进程:+
后台进程:&
可以继续进行命令操作
比如:./mytest &
控制进程有两种方法:
1、ctrl+c,直接退出进程
2、kill -l
kill -选项 进程id
kill -9 (杀死后台进程)
kill 的选项有:
写一段程序:
这时使用ps axj
查看进程运行状态,会发现是 S+
状态的。
但是如果程序变成:
进程运行状态会变成:
这是因为printf打印到现实器等外设,很慢,进程在等待外设就绪。
ps axj
或者 ps aux命令
如果没有人检测或者被父进程回收进程,该进程退出进入Z。僵尸进程会以终止状态保存在进程表中,并且会一直在等待父进程读取退出状态代码。
情况一:子进程退出,父进程没有回收子进程
子进程会变成僵尸进程。
情况二:父进程退出,子进程一直运行。
子进程被1号进程(OS)领养,当子进程退出时,由1号进程回收。父进程先死,子进程的状态是孤儿进程,被OS领养。
1、进程的退出状态必须维持下去,因为他要告诉父进程,你交给我的任务,我办的怎么样?可如果父进程一直不读取,子进程就会一直处于Z状态。
2、维护退出状态本身是用数据维护,也是进程的基本信息,保存在PCB中,如果Z状态一直不退出,PCB就一直都要维护。
3、如果一个父进程创建了多个子进程,就是不回收,会造成内存资源的浪费(数据结构对象本身就要占用内存)-> 会造成内存泄漏!