1. 前言

从宏观的角度来看,操作系统就是我们日常使用的 Windows、MacOS、Linux 这类的系统,但是这种直观的用户交互界面只是操作系统的一小部分功能,操作系统如何决定系统的资源调度、如何处理内存的分配以及如何管理网络和文件系统,这些都是隐藏在用户界面之下的内容。

从课程设计的角度来看,操作系统(Operating System)是计算机专业的核心专业课程,所以可以用来衡量候选人的计算机基本功。

对于后端程序员,如果是使用 Java 语言,Java 中的多线程会涉及到进程和线程的关系,这是操作系统中的概念。如果使用 C++ 语言,那么无法避免内存分配和管理,这也是操作系统中的基础概念,因此操作系统是校招面试中的核心之一。

2. 进程和线程

面试官提问: 操作系统中的进程和线程有什么区别?

题目解析:

进程和线程的区别是操作系统面试相关的出现频率最高的题目,没有之一。

在阐述进程和线程的定义之前,最好能够想清楚在操作系统中为什么会出现进程这个概念。

2.1 进程的产生背景

我们希望操作系统能够同时处理多个任务,例如在播放网易云音乐的同时,也能在微信上聊天。计算机的核心处理硬件是 CPU,如果计算机只有一个 CPU,那么播放音乐和处理聊天软件都需要这个 CPU 去执行运算逻辑,那如何做到时间上的同时处理?答案是 CPU 在多个逻辑任务之间来回切换,因为切换速度太快,所以看起来做到了并发执行。

传统操作系统的任务调度采用时间片轮转的方式,在执行一个任务达到时间限制时会暂停处理,然后切换到处理下一个任务。每一个任务执行的时间间隔就是一个时间片,被执行的任务处于运行状态,被暂停的任务处于就绪状态,如图所示:

图片描述

假设存在两个调度任务,CPU 调度产生并发的 "错觉"

2.2 进程和线程的区别

首先给出进程和线程的基本定义:

  • 进程(Process) :是操作系统任务调度的基本单元, 目的是为了实现操作系统的并发。
  • 线程(Thread) :线程是进程的子任务,是进程中实际运行的任务,线程是程序执行的最小单元。

然后分析两者之间的主要区别:

(1)包含关系:一个线程肯定归属于一个进程,但是一个进程可以包含多个线程。
(2)内存管理:操作系统会给进程分配独立的内存空间,但是一个进程下的多个线程共享内存空间。以 Java 编程为例,同一个 main 函数进程下的多个线程共享代码段(代码和常量),以及数据段(全局变量和静态变量),这些都是共享的内存空间,不过需要注意,每个线程会有独立的运行栈空间。
(3)单元定义:从内存分配的角度就能看出,进程是资源分配的最小单元,线程是 CPU 执行的最小单元。
(4)系统开销:创建进程和线程的系统开销是不同的,因为在创建和销毁进程时,操作系统需要分配和回收内存资源,创建线程不需要切换整体内存空间,所以创建进程的系统开销远大于创建线程;在切换进程时需要保存 CPU 运行的上下文,切换线程只需要切换 CPU 中少数寄存器的内容,所以切换进程的系统开销也远大于切换线程。
(5)稳定性分析:因为不会共用内存空间,所以一个进程挂了对另外的进程影响很小,但是同一进程下的线程是共享内存的,所以一个线程挂了,会影响到其他线程。
(6)通信:因为不同进程处于不同的内存空间,所以通信方式比较麻烦,具体方式将在之后的小节介绍。同一进程下的线程之间通信方式相对简单,因为共享内存,可以读写相同的内存空间。

3. 小结

本章节介绍了操作系统中进程的起源原因,以及从操作系统内存管理的角度分析了进程和线程之间的区别。