操作系统篇一:进程与线程、并发并行与串行、同步与异步、阻塞与非阻塞

2,156 阅读10分钟

当你被问到这些问题:你觉得的并发、并行、串行有什么区别?线程与线程有什么区别和关系?你会怎样回答呢,是不是也有点傻傻分不清楚或者似懂非懂呢。接下来我们就详细介绍下,有描述有错的地方可以留言哦。

并发、并行、串行、线程、进程这些最开始都是操作系统中的概念,表示CPU执行多个任务的方式。首先我们先简单了解下计算机组成的一些知识

计算机的基本硬件组成

首先通过下面这幅图来看下计算机的硬件组成部分以及他们之间关系

多CPU与多核

下面这幅图是我所以使用的Mac的CPU情况

可以看到我的电脑是单CPU,启用了超线程技术6核12线程

多CPU: 是指简单的多个CPU工作在同一个系统上,多个CPU之间的通讯是通过主板上的总线进行的

多核 :是指一个CPU有多个核心处理器,处理器之间通过CPU内部总线进行通讯

那么接下来我们在来讲解开头提到的那几个概念及他们的区别就更容易理解了,我们一一介绍

进程与线程

进程:是操作系统(OS)进行资源(CPU、内存、磁盘、IO、带宽等)分配的最小单位。一个进程就是一个程序的运行实例

启动一个程序的时候,操作系统会为该程序创建一块内存,用来存放代码、运行中的数据和一个执行任务的主线程,我们把这样的一个运行环境叫进程

例如:打开一个浏览器、一个聊天窗口分别是一个进程。进程可以有多个子任务,如聊天工具接收消息、发送消息,这些子任务成为线程。

线程: 是CPU调度和分配的基本单位。操作系统会根据进程的优先级和线程的优先级去调度CPU。

线程数: 是一种逻辑概念,是模拟出的CPU核心数 。

进程将资源分配给线程程,一个进程内线程之间共享进程的资源。他们之间的关系可以参考下图:

进程和线程的关系描述如下:

  • 进程可以简单理解为一个容器有自己独立的地址空间。一个进程可由多个线程的执行单元组成,每个线程都运行在同一进程的上下文中,共享进程该地址空间以及其内的代码和全局数据等资源即线程之间共享进程中的数据

  • 每个进程至少有一个主线程,它无需由用户主动创建,一般由系统自动创建。系统创建好进程后,实际上就启动了执行该进程的执行主线程,执行主线程以函数地址形式,即程序入口函数(如 main函数),将程序的启动点提供给操作系统。主执行线程终止或关闭,进程也就随之终止,操作系统会回收改进程所占用的资源

  • 进程中的任意一线程执行出错,都会导致整个进程的崩溃。

  • 进程之间的内容相互隔离。进程隔离是为保护操作系统中进程互不干扰的技术,每一个进程只能访问自己占有的数据,也就避免出现进程 A 写入数据到进程 B 的情况。正是因为进程之间的数据是严格隔离的,所以一个进程如果崩溃了,或者挂起了,是不会影响到其他进程的。如果进程之间需要进行数据的通信,这时候,就需要使用用于进程间通信(IPC)的机制了。

  • 严格讲应该是线程能够获得CPU资源,进程对CPU资源的获取也是体现在线程上的。CPU内核数,和进程线程没直接关系。操作系统(OS)可以把某个进程部署在某个CPU核上,但这取决于系统设计。

  • 进程、线程都是由操作系统调度的,线程只是由进程创建,但是进程本身不会负责调度线程。在操作系统看来,线程和进程其实差不多,不同点是线程是迷你的进程,并且进程可以包含多个线程

  • 对于内存堆内存、代码区一般属于一个进程,但是栈(执行栈)却是属于一个线程的,且每个线程拥有一个独立的栈。

总结一下:

进程和线程都是CPU工作一个时间段的描述

  • 进程就是上下文切换的程序执行时间总和 = CPU加载上下文+CPU执行+CPU保存上下文

  • 线程是共享了进程的上下文环境,的更为细小的CPU时间段。

两者之间的详细区别可以参考下图:

程序与进程、线程的关系

程序 : 是一组指令的有序集合,是一个静态的实体,本身没有任何运行的含义。

进程 : 是程序在某个数据集上的执行, 即进程是程序的一次执行,是一个动态的实体,有自己的生命周期,因创建而产生、因调度而运行、因等待资源或事件而被处于等待状态、因任务完成而被撤销,反映的是一个程序在一定的数据集上运行的全部动态过程。

无论系统有几个CPU,每个进程运行在单个CPU上,如果单CPU有多个进程则多个进程并发执行。

线程 : 程序执行的最小单元,每个程序都至少有一个线程,若程序只有一个线程,那就是它程序本身。单线程的进程可以简单地理解为只有一个线程的进程,一个进程在同一时间只做一件事。多线程的进程可以理解为一个进程同一时间段做多件事,每个线程可以处理不同的事务,一个线程阻塞不会影响另一个线程。

来看下在多线程和单线程中分别是怎样执行如下三个运算的

A = 1 + 2
B = 4 - 3
c= 5 * 6

从图中可以看到,线程是依附于进程的,而进程中使用多线程并行处理能提升运算效率

多线程的进程可以尽可能地利用系统CPU资源,但也不是线程越多越好,线程越多CPU分配给每个线程的时间就越少。

进程和程序关系:

  • 两者并不是一一对应的,一个程序执行在不同的数据集上就成为不同的进程,可以用进程控制块来唯一地标识每个进程,这是程序无法做到的,因为程序没有和数据产生直接的联系,即使是执行不同的数据的程序。

  • 一般来说,一个进程一定有一个与之对应的程序,而且只有一个;而一个程序有可能没有与之对应的进程因为它没有执行、也可能有多个进程与之对应因为它运行在不同的数据集上。

不同的进程可以执行同一段程序,比如读取同一个文件数据,它们的读取函数的代码是相同的,并被多个进程或线程运行了

通过对操作系统、计算机组成、线程进程等知识的学习了解,那么下面我们再进行并发、并行、串行的讲解就更容易理解了,那么他们之间有什么区别呢以及和CPU及其核数有什么关联呢?

并发、并行、串行

让我们来用一幅图描述下三者的不同,这将有利于我们更直观的理解他们之间的区别在单核CPU中CPU是无法被多个程序并行使用的,多个进程或多个线程内能实现并发(微观上串行,宏观上并发);多核CPU线程间可以实现微观上的并行。

举个开发中我们说资源请求并发数达到了1万。这里的意思是有1万个请求同时过来了。但是这里很明显不可能真正的同时去处理这1万个请求的。

如果这台机器的处理器有4个核心,不考虑超线程,那么我们认为同时会有4个线程在跑。也就是说并发访问数是1万,而底层真实的并行处理的请求数是4

如果并发数小一些只有4的话,又或者你的机器牛逼有1万个核心,那并发在这里和并行一个效果。

也就是说,并发可以是虚拟的同时执行,也可以是真的同时执行。而并行的意思是真的同时执行

总结:

1、单CPU中进程只能是并发,多CPU计算机中进程可以并行。
2、单CPU单核中线程只能并发,单CPU多核中线程可以并行。
3、无论是并发还是并行,使用者来看,看到的是多进程,多线程。

同步与异步

同步和异步关注的是消息通信机制

同步:同步是指一个进程在执行某个请求的时候,如果该请求需要一段时间才能返回信息,那么这个进程会一直等待下去,直到收到返回信息才继续执行下去。

异步:异步是指进程不需要一直等待下去,而是继续执行下面的操作,不管其他进程的状态,当有信息返回的时候会通知进程进行处理,这样就可以提高执行的效率了,即异步是我们发出的一个请求,该请求会在后台自动发出并获取数据,然后对数据进行处理,在此过程中,我们可以继续做其他操作,不管它怎么发出请求,不关心它怎么处理数据。

举个例子:

你打电话问书店老板有没有《操作系统》这本书,如果是同步通信机制,书店老板会说,你稍等,”我查一下",然后开始查啊查,等查好了(可能是5秒,也可能是一天)告诉你结果(返回结果)。
而异步通信机制,书店老板直接告诉你我查一下啊,查好了打电话给你,然后直接挂电话了(不返回结果)。然后查好了,他会主动打电话给你。在这里老板通过“回电”这种方式来回调

阻塞与非阻塞

阻塞和非阻塞关注的是程序在等待调用结果(消息,返回值)时的状态.

阻塞调用:是指调用结果返回之前,当前线程会被挂起。调用线程只有在得到结果之后才会返回。

非阻塞调用:指在不能立刻得到结果之前,该调用不会阻塞当前线程。

还是上面的例子:

你打电话问书店老板有没有《操作系统》这本书,你如果是阻塞式调用,你会一直把自己“挂起”,直到得到这本书有没有的结果,如果是非阻塞式调用,你不管老板有没有告诉你,你自己先一边去玩了, 当然你也要偶尔过几分钟check一下老板有没有返回结果。

阻塞与非阻塞与是否同步异步无关。跟老板通过什么方式回答你结果无关。

提高计算机性能的两种方式

  • 提高硬件水平,处理速度或核心数。

  • 另根据实际场景,合理设置线程数,软件上提高CPU利用率。

参考:

计算机组成原理

我要理解的CPU、核心,进程、线程,串行、并发、并行