5万字、97 张图总结操作系统核心知识点 (4)

进程在创建之后,它就开始运行并做完成任务。然而,没有什么事儿是永不停歇的,包括进程也一样。进程早晚会发生终止,但是通常是由于以下情况触发的

正常退出(自愿的) : 多数进程是由于完成了工作而终止。当编译器完成了所给定程序的编译之后,编译器会执行一个系统调用告诉操作系统它完成了工作。这个调用在 UNIX 中是 exit ,在 Windows 中是 ExitProcess。

错误退出(自愿的):比如执行一条不存在的命令,于是编译器就会提醒并退出。

严重错误(非自愿的)

被其他进程杀死(非自愿的) : 某个进程执行系统调用告诉操作系统杀死某个进程。在 UNIX 中,这个系统调用是 kill。在 Win32 中对应的函数是 TerminateProcess(注意不是系统调用)。

进程的层次结构

在一些系统中,当一个进程创建了其他进程后,父进程和子进程就会以某种方式进行关联。子进程它自己就会创建更多进程,从而形成一个进程层次结构。

UNIX 进程体系

在 UNIX 中,进程和它的所有子进程以及子进程的子进程共同组成一个进程组。当用户从键盘中发出一个信号后,该信号被发送给当前与键盘相关的进程组中的所有成员(它们通常是在当前窗口创建的所有活动进程)。每个进程可以分别捕获该信号、忽略该信号或采取默认的动作,即被信号 kill 掉。整个操作系统中所有的进程都隶属于一个单个以 init 为根的进程树。

5万字、97 张图总结操作系统核心知识点

Windows 进程体系

相反,Windows 中没有进程层次的概念,Windows 中所有进程都是平等的,唯一类似于层次结构的是在创建进程的时候,父进程得到一个特别的令牌(称为句柄),该句柄可以用来控制子进程。然而,这个令牌可能也会移交给别的操作系统,这样就不存在层次结构了。而在 UNIX 中,进程不能剥夺其子进程的 进程权。(这样看来,还是 Windows 比较渣)。

进程状态

尽管每个进程是一个独立的实体,有其自己的程序计数器和内部状态,但是,进程之间仍然需要相互帮助。当一个进程开始运行时,它可能会经历下面这几种状态

5万字、97 张图总结操作系统核心知识点

图中会涉及三种状态

运行态,运行态指的就是进程实际占用 CPU 时间片运行时

就绪态,就绪态指的是可运行,但因为其他进程正在运行而处于就绪状态

阻塞态,除非某种外部事件发生,否则进程不能运行

进程的实现

操作系统为了执行进程间的切换,会维护着一张表,这张表就是 进程表(process table)。每个进程占用一个进程表项。该表项包含了进程状态的重要信息,包括程序计数器、堆栈指针、内存分配状况、所打开文件的状态、账号和调度信息,以及其他在进程由运行态转换到就绪态或阻塞态时所必须保存的信息。

下面展示了一个典型系统中的关键字段

5万字、97 张图总结操作系统核心知识点

第一列内容与进程管理有关,第二列内容与 存储管理有关,第三列内容与文件管理有关。

现在我们应该对进程表有个大致的了解了,就可以在对单个 CPU 上如何运行多个顺序进程的错觉做更多的解释。与每一 I/O 类相关联的是一个称作 中断向量(interrupt vector) 的位置(靠近内存底部的固定区域)。它包含中断服务程序的入口地址。假设当一个磁盘中断发生时,用户进程 3 正在运行,则中断硬件将程序计数器、程序状态字、有时还有一个或多个寄存器压入堆栈,计算机随即跳转到中断向量所指示的地址。这就是硬件所做的事情。然后软件就随即接管一切剩余的工作。

当中断结束后,操作系统会调用一个 C 程序来处理中断剩下的工作。在完成剩下的工作后,会使某些进程就绪,接着调用调度程序,决定随后运行哪个进程。然后将控制权转移给一段汇编语言代码,为当前的进程装入寄存器值以及内存映射并启动该进程运行,下面显示了中断处理和调度的过程。

硬件压入堆栈程序计数器等

硬件从中断向量装入新的程序计数器

汇编语言过程保存寄存器的值

汇编语言过程设置新的堆栈

C 中断服务器运行(典型的读和缓存写入)

调度器决定下面哪个程序先运行

C 过程返回至汇编代码

汇编语言过程开始运行新的当前进程

一个进程在执行过程中可能被中断数千次,但关键每次中断后,被中断的进程都返回到与中断发生前完全相同的状态。

线程

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpswxs.html