操作系统设计/进程
进程不仅仅是程序在内存中的一个副本。可执行程序就像一个食谱。它是一系列计算机按顺序读取以完成任务的指令。当厨师准备菜肴时,他会阅读食谱,收集食谱中需要的材料,并按照食谱指示将它们组合在一起。这类似于程序运行的方式。
当您在计算机上运行程序时,操作系统会收集资源(如内存和 CPU 时间)并开始按照可执行文件中列出的指令进行操作。操作系统必须跟踪它在任何给定时间执行的指令以及程序的当前状态。所有这些信息,包括程序本身、分配给它的资源列表及其状态信息,都是进程的一部分。
在多任务操作系统中,如 Windows(95 及更高版本)、Linux 和 MacOS,多个进程可以由操作系统同时运行,每个进程轮流在 CPU 上运行。操作系统为每个进程分配时间在 CPU 上运行,并在它们之间快速切换,以至于它们看起来是同时运行的。MS-DOS 在 Microsoft Windows 之前,一次只运行一个进程。
进程用于执行计算机需要执行的每项任务。操作系统本身就是一个进程。它会生成(或启动)运行显示、与键盘交互、运行鼠标并与磁盘驱动器交互的进程。用户启动了一些进程,例如文字处理器、电子表格、网页浏览器和电子邮件客户端。其中一些程序由多个协作进程组成;例如,一个 Web 服务器可能有多个进程来同时处理多个传入请求。
在设计操作系统时,重要的是进程间通信,或 IPC。本质上,当多个进程运行并共享同一台计算机时,有时这些进程可能需要与另一个进程通信,或者多个进程可能需要共享相同的资源。当这种情况发生时,应注意不要创建某些危险条件,即竞争条件,其中两个进程尝试同时使用相同的资源。哪个速度更快就先获得机会,但另一个进程随后获得下一个机会,依此类推,使资源混乱。当两个设备都锁定到等待模式时,会发生死锁,等待另一个设备完成才能启动,因此两者都无法完成,其他更罕见且更难预测的错误也会发生,更难以调试。
主要问题是控制进程的进程需要时间,在此期间,另一个进程可能会尝试使用相同的资源。要并发运行多个进程,需要确保在任何时间点,只有一个进程可以访问资源,并且在锁定资源以供访问时,另一个进程无法中断处理并干扰它。防止这种情况发生的一种方法是在硬件中构建原子命令,这些命令在它们与资源的关键关联时无法中断。许多此类进程已被尝试,包括锁、信号量、互斥锁、监视器等。最新技术称为消息传递技术,它与 OOP 配合良好。
尽管线程有时不被认为是真正的进程,因为它们不承载完整的进程的所有负载,但使用线程的并发与进程间通信一样充满了问题。主要区别在于线程不会附加完整的进程必须的所有资源。具体区别在于进程的上下文字段。线程不会拥有自己的上下文,而是继承了它们所生成的父进程的上下文,因此必须注意它们不会在没有某种通信同步的情况下更改其他线程使用的变量。
线程有时被称为轻量级进程。进程和线程都提供执行环境,但创建新线程通常比创建新进程需要的资源少。
线程存在于进程中——每个进程至少有一个线程。线程共享进程的资源,包括内存和打开的文件。这使得通信既高效又可能存在问题。
多线程执行是 Java 平台的一项重要功能。每个应用程序至少有一个线程——或者如果算上执行内存管理和信号处理等操作的“系统”线程,则有多个线程。但从应用程序程序员的角度来看,您从一个线程开始,称为主线程。该线程能够创建其他线程,我们将在下一节中演示。