进程和线程
进程和线程在操作系统中是比较重要的内容,面试中的基础提问也经常会出现,如进程和线程的区别等等,如果没有仔细梳理,还真的很难说清楚。本文仅列出进程和线程的基本内容及区别。
在一些操作系统的书籍中,通常会介绍到多任务系统,现代的操作系统基本都是支持 “多任务”,简单地说,多任务指的是操作系统可以同时运行多个任务。比如我现在一边在MacDown
写东西,一边听音乐,一边在用浏览器看文章。
现在,多核CPU非常普及,在这之前使用的单核CPU,也是可以执行多任务,由于CPU执行代码都是顺序执行,那么单核CPU如何执行多任务?答案是操作系统按一定时间分配CPU给任务1、任务2…,任务之间交替使用CPU执行,由于CPU的执行速度快且任务之间的切换时间间隔很短,因此就有多个任务同时执行一样。
在多核CPU上能够实现真正的并行执行多任务,操作系统自动把多个任务轮流调度到CPU的每个核心上执行。
对操作系统而言,一个任务就是一个进程(Process)。进程有可能不止同时做一件事,比如音乐播放器可以一边播放音乐,一边搜索歌曲。在进程内部同时执行的多个“子任务”,它们是在多个线程(Thread)上执行。
所以,进程至少有一个线程。同样地,在单核CPU中,多个线程之间可以快速切换实现多线程并发;在多核CPU中,多个线程在不同核心上执行,实现了多线程并行。
CPU | 进程 | 线程 |
---|---|---|
单核 | 多进程并发,多个进程时间片轮换 | 多线程并发,同一进程内的线程轮换 |
多核 | 并行,不同进程的线程使用不同核心 | 并行,多个线程使用不同的核心 |
进程
程序本身只是指令、数据及其组织形式的描述,进程才是程序的真正运行实例。在分时系统中,进程是基本的运作单位,但是在当代多数面向线程设计的系统中,进程本身不是基本运行单位,而是线程的容器。进程内包含一个或多个线程(每一个线程都代表一个进程内的一个独立执行上下文)
进程内容
一个进程可以包括下列数据:
- 程序可执行文件二进制在内存中的映像
- 分配到的内存(通常是虚拟内存)。虚拟内存中包括可执行代码、调用堆栈、堆栈
- 分配给该进程的资源的操作系统描述符,诸如文件描述符(Unix术语)或文件句柄(Windows)、数据源和数据终端。
- 安全特性,诸如进程拥有者和进程的权限集(可以容许的操作)。
- 处理器状态(内文),诸如寄存器内容、物理存储器定址等。当进程正在运行时,状态通常存储在寄存器,其他情况在存储器。
进程状态
- 新生(new):进程新产生中。
- 运行(running):正在运行。
- 等待(waiting):等待某事发生,例如等待用户输入完成。亦称“阻塞”(blocked)
- 就绪(ready):排队中,等待CPU。
- 结束(terminated):完成运行。
各状态名称可能随不同操作系统而相异;对于单CPU系统(UP),任何时间可能有多个进程为等待、就绪,但必定仅有一个进程在运行。
注意: 进程的各个状态之间是不能随意切换的,例如当进程运行时因IO操作而阻塞,当IO操作完成后并不会直接恢复回运行态,而是转为就绪态等待CPU的调度。
线程
大部分情况下,线程被包含在进程之中,是进程中的实际运行单位。一条线程是指进程中一个单一顺序的指令流。在多核CPU中,一个进程中可以并发多个线程,每条线程并行执行不同任务。同一进程中的多条线程将共享该进程中的全部系统资源,如虚拟地址空间,文件描述符和信号处理等等。但同一进程中的多个线程有各自的调用栈(call stack),自己的寄存器环境(register context),自己的线程本地存储(thread-local storage)。
线程状态
- 产生(spawn)
- 中断(block)
- 非中断(unblock)
- 结束(finish)
联系与区别
- 进程比线程携带更多状态信息,而一个进程中的多个线程共享进程状态和其他资源
- 进程有独立的地址空间,而线程共享进程的地址空间
- 进程通过系统提供的进程间通信机制进行交互
- 进程中的线程间上下文切换通常比进程之间上下文切换要快