Multi-tasks With Process & Thread
现代操作系统都是「多任务」的,也就是操作系统可以「并发」处理多个任务,比如可以在浏览页面的时候同时播放音乐,但是一般来说我们的 PC 一般都只有一个物理 CPU,那么是如何做到只有一个 CPU 的情况下并发处理多个任务的呢,我们简单探究一下。
前置知识
我们先简单熟悉一下需要理解的 CPU 硬件相关的术语
1.Sockets(physical CPU): 物理 CPU,指我们主板上实际插入的 CPU,一般来说 PC 只有一个,服务器可能会有多个
2.Cores: CPU 物理核心,CPU 商品上宣传的一共几核指代的就是这个
3.Logical Processors: 逻辑处理器,如果采用超线程(多线程)技术的话,会比物理核心数多
总的来说: Logical Processors = Sockets _ Cores _ SMT(HT) Multiple
逻辑处理器数量也就代表了操作系统认为能「并行」执行的任务的最高数量
并发 VS 并行
我们对「并发」和「并行」先下个定义,「并发」指的是系统允许多个任务同时存在,「并行」则指的是系统支持多个任务同时执行,「并发」和「并行」的关键区别在于是否能同时执行。在只有单一逻辑处理器的情况下,我们的操作系统只能「并发」执行任务,比如早期的单核 CPU 电脑,但是我们仍然可以边听歌边浏览网页,这是因为 CPU 速度足够快,可以在系统的使用过程中快速切换任务,这样我们就感觉到多个任务同时存在。在单一逻辑处理器的情况下,虽然我们可以「并发」执行任务,实际上我们同时也只能执行一个任务,对于 IO 密集类型的任务,我们用到 CPU 的时间不多,决定任务快慢的往往是硬盘以及网络等硬件,「并发」执行也未尝不可,但是对于计算密集型的任务,我们需要占用更多的 CPU 时间,如果「并发」执行,则往往会造成任务的卡顿(响应时间过长),因此我们需要「并行」的执行该任务,而逻辑处理器的数量代表了能「并行」执行任务的最高数量,这也是为什么现在的处理器大多是多核处理器的原因所在。
进程 VS 线程
我们使用的一个个程序可以称为「进程」(process),而 process 下可以开辟多个「线程」(thread),这里引用一下 Microsoft 官方对于进程和线程的解释About Processes and Threads:
Each process provides the resources needed to execute a program. A process has a virtual address space, executable code, open handles to system objects, a security context, a unique process identifier, environment variables, a priority class, minimum and maximum working set sizes, and at least one thread of execution. Each process is started with a single thread, often called the primary thread, but can create additional threads from any of its threads.
A thread is the entity within a process that can be scheduled for execution. All threads of a process share its virtual address space and system resources. In addition, each thread maintains exception handlers, a scheduling priority, thread local storage, a unique thread identifier, and a set of structures the system will use to save the thread context until it is scheduled. The thread context includes the thread’s set of machine registers, the kernel stack, a thread environment block, and a user stack in the address space of the thread’s process. Threads can also have their own security context, which can be used for impersonating clients.
在操作系统层面,process 相互独立,拥有一块独立的虚拟地址空间(内存中),而同一 process 下的 thread 共享该虚拟地址空间,这也是 process 和 thread 最典型,最根本的区别
多进程 VS 多线程
假如我们现在要开发一款浏览器,浏览器的基础功能包括 HTTP 请求,GUI 渲染等功能,如果我们采用单线程来开发,那么势必会遇到一个问题: 当需要网络请求的时候,我们的浏览器就会卡住,所有的用户操作如输入等都没有响应,等网络请求完成,我们才可以进行后续操作,非常影响用户体验,这也是为什么像浏览器这样的程序大多都是多线程的原因,我们需要任务同时进行。但是我们前面讲到的多进程也可以多任务同时进行,那么问题就来了,当我们需要实现多任务的时候,多进程和多线程该如何选择呢?