操作系统进程状态操作系统中进程的概念大致分为三种运行、阻塞、挂起运行runing如上图只要在调度队列中的进程其状态就是运行状态。阻塞当执行一个进程时需要等待某种设备或资源就绪才可以继续执行时。就会因其需要等待而进入阻塞状态。比如需要执行scanf就要等待键盘发送数据给计算机。如图假设当前进程需要执行scanf等待键盘的数据。操作系统就会将当前这个进程从运行队列中拿出并链接至对应硬件的等待队列中wait queue当对应硬件有响应时操作系统会第一时间得知并再次将对应的进程链接回运行队列。在等待队列中的进程状态就是阻塞状态阻塞状态下的进程不能被执行。挂起挂起状态是一个极端情况下会触发的状态。当内存空间不足时操作系统为了正常的运行就会将阻塞状态的进程的代码和数据唤入到磁盘中具体为磁盘的swap交换分区。当需要执行该进程时再将代码和数据从swap交换分区中唤出并链接至运行队列。极端情况下操作系统甚至可能把运行队列末端的进程进行挂起。如果一个进程的代码和数据被唤入swap交换分区这个进程的状态就是挂起状态。进程状态的变化其表现之一就是在不同队列中流动本质就是对不同的数据结构进行增删改查。理解内核中的链表【Linux】初见进程概念-CSDN博客在上文我们讲到了linux中stack_struct的组织方式是双链表。而上面我们又讲到了CPU的调用是通过调度队列实现的。 这就很矛盾了在我们之前的学习中一个元素只可能属于一个数据结构。难道这里是不符合常理的吗是的这里的元素即属于双链表又属于队列。可以同时属于多个数据结构内核中的实现方式与我们之前见到的有显著区别。 内核中将前后指针单独作为一个元素放在结构体中。那么问题就来了内核中是如何实现找到其他成员变量的呢1.找到links变量在结构体中的偏移量 2.links的地址减去links的偏移量就得到了结构体的起始地址。代码语言javascriptAI代码解释prev/list - ((struct task_struct*)0) - links((struct task_struct*)0) - links的作用就是获得links的偏移量。运算符 - 的底层运行原理是基地址 偏移量 目标地址而偏移量是编译器在编译过程中自动推导的既编译过程时就确定了每个成员的偏移量((struct task_struct*)0) - links 其实也是宏 offsetof 的实现原理这里我们让0作为了基地址0 偏移量 目标地址。于是我们通过 - 运算符得到的目标地址就是偏移量。前面的就好理解了通过这个我们就可以得到结构体的起始地址。得到起始地址那么访问任意一个元素就没有任何困难了。推导再上面的基础上我们再添加多个links就可以实现一个元素同时连接至多个数据结构。不论是双链表、队列、单链表等等等等都可以实现Linux进程状态上面讲到的操作系统进程状态是笼统的大概念。下面我们来讲讲具体的操作系统下进程的状态代码语言javascriptAI代码解释static const char *const task_state_array[] { R (running), /*0 */ S (sleeping), /*1 */ D (disk sleep), /*2 */ T (stopped), /*4 */ t (tracing stop), /*8 */ X (dead), /*16 */ Z (zombie), /*32 */ };如上述linux中的进程共有7种。在task_struct中用整型来表示进程的状态。运行状态Rrunning与上述无异既在运行队列中的进程即为运行状态阻塞状态Ssleeping与Ddisk sleepS可中断休眠浅睡眠。可以被信号唤醒当等待的事件发生键盘输入时也会被唤醒D不可中断休眠深度睡眠。通常用于等待磁盘I/O操作完成。等待I/O操作的过程中进程等待磁盘的响应结果以反馈给用户所以不希望被打断。只有当I/O操纵完成时进程才会被唤醒。停止状态Tstopped可以通过发送SIGSTOP信号给进程来停止T进程。这个被暂停的 进程可以通过发送SIGCONT信号让进程继续运行。也可以通过调试打断点来实现停止状态。僵尸状态重要Zzombie是一个比较特殊的状态。当进程退出并且父进程没有读取到子进程的退出代码时就会进入僵尸状态。僵尸进程会一直在进程列表中保持退出状态直到父进程读取带退出代码。僵尸进程的危害进程的退出状态必须被维护下去因为子进程的执行结果必须要告知父进程才行。如果父进程一直没来读取子进程的退出代码那么子进程就会一直处于僵尸状态。进程的退出状态也是属于进程的基本信息所以会保存在task_struct中。也就是说Z状态一直不退出task_struct就一直维护父进程不回收子进程就导致内存资源的浪费既内存泄漏。因为进程的task_struct是一个结构体对象其本身就要占用内存。孤儿进程在一组父子进程中如果父进程比子进程先退出怎么办父进程退出不用但是因为父进程一定有它的父进程。但子进程这下就没有父进程了如果后面子进程也要退出没有父进程回收那岂不是出问题了所以对于父进程先退出的子进程操作系统会让1号进程“领养”子进程。而这个被领养的子进程就叫作孤儿进程。并且孤儿进程会自动转化为后台进程后台进程不能使用指令ctrl c 杀掉