在上一篇已经了解了在进程中的基本概念,现在我来了解一下进程的相关状态;
对于进程的状态,在详细了解之前我们可以来一个粗略的理解:进程的状态可以理解为就是一个整数,用宏定义 实现R, S等状态;也就是进程状态就是take_struck内的一个整数;
如果不理解也没关系,下面来看看对进程状态的看法:
先理解最基本的三个状态运行&&阻塞&&挂起
运行&&阻塞&&挂起
每一个cpu中都有一个 调度队列(Linux中叫做runqueue)的东西;
之前的文章就提到过,找到PCB就能找到对应的代码和数据,而调度队列本就是专门文CPU设计的一个队列;PCB既属于全局链表也属于调度队列;至于原因在Linux内核链表详细说明;
- 运行:只要进程在调度队列中,进程的状态就是running;
- 阻塞:等待某种设备或者资源就绪(如键盘,显示器,网卡,磁盘,摄像头,话筒……)
最常见的阻塞的例子,C语言的scanf 在输入是就是阻塞,等待键盘输入;
当然OS要管理系统中的各种硬件资源还是要先管理,后组织的;
因此OS中也存在 设备队列
假设运行队列的一个进程,想要键盘输入,但是键盘正在被调度,这个进程就会被连入设备队列的键盘对应的 device 的等待指针(wait queue)中。当键盘有空时,OS 先改变其 state 等……一系列状态,再找其等待队列指针中是否有等待的进程,有,则再把进程取消链接,链入到原来的进程中;
总之:
运行到阻塞其实:就是把 PCB(进程) 连入到了不同的队列结构当中;
从阻塞到运行;其实就是把找到 PCB,在把 PCB 连回到原来的队列中。(这和面试那个例子很像)
- 阻塞挂起:当内存吃紧时,正处于阻塞状态的进程的代码和数据被 唤出 到磁盘的特定地方处于这个状态的进程 就是 阻塞挂起。(这个特定的地方可以称为 swap交换分区)
当某个进程等待的设备已经有空进行这个进程时,肯定也是 OS 先知道的;OS 就先会把磁盘的特定地方的对应的代码和数据唤入到对应的进程中;再把 进程状态变为 running
当内存相当吃紧时;汇报 运行队列中的进程的代码和数据唤出到 swap 交换分区,这一过程为运行挂起;(因此挂起这一操作,在很多地方的能进行);
理解内核链表
我们知道Linux的内核链表是双链表,但是是传统的双链表吗?
其实Linux的内核链表不是传统的双链表
Linux 中 next prev 指向的不是一个一个节点,而是一个(节点)进程内部的 links进程
Linux就是用这种结构用一个进程 实现了各种队列(如运行队列,设备队列)
也是就 list_head 存储 struc task 的各种不同类型的信息。(设备链表,进程链表,软件链表等等一类的)
Linux的进程状态
下面是比较官方的定义:
- R运行状态(running): 并不意味着进程一定在运行中,它表明进程要么是在运行中要么在运行队列里。
- S睡眠状态(sleeping): 意味着进程在等待事件完成(这里的睡眠有时候也叫做可中断睡眠(interruptible sleep))。
- D磁盘休眠状态(Disk sleep)有时候也叫不可中断睡眠状态(uninterruptible sleep),在这个状态的进程通常会等待IO的结束。
- T停止状态(stopped): 可以通过发送 SIGSTOP 信号给进程来停止(T)进程。这个被暂停进程可以通过发送 SIGCONT 信号让进程继续运行。
- X死亡状态(dead):这个状态只是一个返回状态,你不会在任务列表里看到这个状态。
指令查看
每过一秒查看这个进程
R状态
为什么./myprocess 没有R状态? 主要原因就是R状态就在打印的那一瞬间,时间很短,运气好多才能查看到R状态 ;
printf()运行 IO 状态很短,很难察觉到
T状态
为什么叫断点?因为进程被暂停了
不是被追踪而暂停的,而是用户 ctrl z 让其暂停的;那么作用是什么呢:一般是用于止损的,比如一个软件不让你评论但是评论了,OS 就会把这个进程暂停;再由用户决定是否删除这个进程;
S状态与D状态
OS中的阻塞状态,在Linux中就是S,把Linux的睡眠状态就是OS中的阻塞状态;
S可以认为是浅睡眠,是可以被杀掉的;而D是深度睡眠,不能被中断;
那为什么要有这个区分呢:
在磁盘完成写入 100MB 的内容之前,进程会在外面等待磁盘完成(此时是 S 状态,浅睡眠)OS 在内存极度紧张的时候,已经把该挂起的挂起了;此时就会把这个浅睡眠状态的进程杀掉;以防重要的进程被当做浅睡眠杀掉,就有了 D 状态;因此 D 状态也是阻塞的一种;
(补充:OS 如果内容真完全不够使用了,OS 就不会进行 OI 操作;操作系统就会崩溃)
X状态
这个状态只是一个返回状态,你不会在任务列表里看到这个状态
补充:为什么ctrl z/ v 能杀掉进程?
标签:状态,队列,链表,概念,Linux,进程,OS From: https://blog.csdn.net/2302_80253411/article/details/145035711因为发送了信号,这是底层原因;
(比如kill -9就是杀掉信号)