面试高频考点:一文吃透并发Concurrency与并行Parallelism

news/2025/3/5 22:44:26/

并发Concurrency)和并行Parallelism)是系统设计中最容易被误解的两个概念。

虽然它们听起来很相似,但实际上指的是处理任务的两种截然不同的方法。

简单来说,一个是关于同时管理(manage)多个任务,而另一个是关于同时执行(execute)多个任务。

在本文中,我们将剖析这两个概念之间的差异,探讨它们的工作原理,并通过示例和代码来说明它们在现实世界中的应用。

1. 什么是并发

并发意味着一个应用程序同时在多个任务上取得进展。
Concurrency means an application is making progress on more than one task at the same time.

在计算机中,任务是通过中央处理器(CPU)来执行的。

虽然单个CPU一次只能处理一个任务,但它通过在任务之间快速切换来实现并发

例如,在编写代码的同时播放音乐。CPU在这些任务之间快速交替,以至于对用户来说,感觉这两个任务是同时进行的。

在这里插入图片描述

这种由现代CPU设计实现的无缝切换,创造了多任务处理(illusion of multitasking)的假象,给人一种任务并行运行的错觉。

然而,需要注意的是,这并不是并行(parallel),而是并发(concurrent)。

并发(concurrency)主要是通过线程来实现的,线程是进程中最小的执行单元。CPU在线程之间切换,以并发地处理多个任务,确保系统保持响应性。

并发的主要目标是通过最小化空闲时间来最大化CPU利用率

例如:

  • 当一个线程或进程在等待输入输出操作、数据库事务或外部程序启动时,CPU可以将资源分配给另一个线程。

这确保了即使个别任务被暂停,CPU仍然能够保持高效运行。

并发是如何工作的?

CPU中的并发是通过上下文切换来实现的。

其工作原理如下:

  1. 上下文保存:当CPU从一个任务切换到另一个任务时,它会将当前任务的状态(例如,程序计数器、寄存器)保存在内存中。
  2. 上下文加载:然后CPU加载下一个任务的上下文,并继续执行该任务。
  3. 快速切换:CPU重复这个过程,在任务之间快速切换,使得这些任务看起来像是在同时运行。

上下文切换的代价

虽然上下文切换实现了并发,但它也引入了额外的开销:

  1. 每次切换都需要保存和恢复任务状态,这会消耗时间和资源。
  2. 过多的上下文切换会增加CPU的开销,从而降低性能。

并发在现实世界中的例子

  1. 网络浏览器

现代网络浏览器会并发地执行多个任务:

  • 渲染网页(HTML/CSS)。
  • 获取外部资源,如图像和脚本。
  • 响应用户操作,如点击和滚动。

这些任务中的每一个都由单独的线程管理,确保浏览器在加载和显示内容时保持响应性。

  1. Web服务器

像Apache或Nginx这样的Web服务器会并发地处理多个客户端请求:

  • 每个请求都使用线程或异步输入输出独立处理。
  • 例如,服务器可以同时处理多个用户加载不同页面的请求,而不会出现阻塞。
  1. 聊天应用程序

聊天应用程序会并发地执行几个操作:

  • 处理传入的消息。
  • 用新消息更新用户界面。
  • 发送传出的消息。

这确保了实时通信的流畅性,不会出现延迟或卡顿。

  1. 视频游戏

视频游戏在很大程度上依赖并发来提供沉浸式体验:

  • 渲染图形。
  • 处理用户输入(例如,角色移动)。
  • 模拟物理效果。
  • 播放背景音乐。

例如,当玩家移动角色时,游戏会同时更新环境并播放音乐,确保游戏运行流畅。

代码示例

大多数流行的编程语言都内置了对创建和管理线程的支持。

下面是一个用Java编写的并发程序示例:
在这里插入图片描述
输出(交错执行):

Task A - Step 1
Task B - Step 1
Task C - Step 1
Task A - Step 2
Task B - Step 2
Task C - Step 2
...

2. 什么是并行

并行意味着多个任务同时被执行。
Parallelism means multiple tasks are executed simultaneously.

为了实现并行,一个应用程序会将其任务分成更小的、独立的子任务。这些子任务被分配到多个CPU、CPU核心、GPU核心或类似的处理单元上,从而使它们能够并行处理。
在这里插入图片描述

为了实现真正的并行,你的应用程序必须:

  1. 使用多个线程。
  2. 确保每个线程被分配到一个单独的CPU核心或处理单元上。

并行是如何工作的?

现代CPU由多个核心组成。每个核心都可以独立地执行一个任务。并行是将一个问题分解成更小的部分,并将每个部分分配给一个单独的核心进行同时处理。
在这里插入图片描述

  1. 任务划分:将问题分解为更小的独立子任务。
  2. 任务分配:将子任务分配到多个CPU核心上。
  3. 执行:每个核心同时处理其分配的任务。
  4. 结果聚合:将所有核心的结果组合起来,形成最终输出。

并行在现实世界中的例子

  1. 机器学习训练
    训练深度学习模型涉及将数据集分成更小的批次。
    每个批次同时在多个GPU或CPU核心上进行处理,显著加快了训练过程。

  2. 视频渲染
    视频帧是独立渲染的,这使得可以同时处理多个帧。
    例如,在使用多个核心并行处理不同帧时,渲染3D动画会快得多。

  3. 网络爬虫
    像谷歌爬虫(Googlebot)这样的网络爬虫会将URL列表分成更小的块,并并行处理它们。
    这使得爬虫可以同时从多个网站获取数据,减少了收集信息的时间。

  4. 数据处理
    像Apache Spark这样的大数据框架利用并行性来处理海量数据集。
    诸如分析数百万用户的日志等任务被分配到一个集群中,实现了同时处理并能更快地获得洞察。

  5. 科学模拟
    像天气建模或分子相互作用这样的模拟需要大量的计算。
    这些计算被分配到多个核心上,实现了同时执行并能更快地得到结果。

代码示例

下面是一个用Java编写的简单并行示例,使用ForkJoinPool框架来并行计算数组的总和:
在这里插入图片描述

  1. 任务拆分:将数组分成更小的段,直到段的大小低于阈值。
  2. 并行执行:使用ForkJoinPool中的单独线程并行执行子任务。
  3. 结果组合:将所有子任务的结果组合起来,计算出最终的总和。

4. 并发并行的组合

  1. 并发但不并行

一个应用程序可以是并发的但不是并行的。在这种情况下:

  • 应用程序看起来同时在多个任务上取得进展(并发)。
  • 然而,它是通过快速在任务之间切换来实现的,而不是同时运行这些任务。
  • 例如:一个单核CPU在任务之间交替,给人一种多任务处理的错觉。
  1. 并行但不并发

一个应用程序可以是并行的但不是并发的。在这种情况下:

  • 一个单一任务被分成子任务,并且这些子任务在单独的核心上同时执行。
  • 任务之间没有重叠;一个任务(及其子任务)在另一个任务开始之前完成。
  • 例如:视频渲染,其中一个单一视频被分成帧,并且每一帧都并行处理。
  1. 既不并发也不并行

有些应用程序既不是并发的也不是并行的。这意味着:

  • 任务是按顺序依次执行的,一次执行一个,没有任何重叠或并行执行。
  • 例如:一个单核CPU,其中只有一个任务被处理,并且在处理下一个任务之前,该任务会完全完成。
  1. 并发并行

一个应用程序可以既是并发的又是并行的,结合了两种执行模型的优点。

在这种方法中:

  • 多个任务同时取得进展,并且每个任务也被分成子任务,这些子任务并行执行。

  • 例如:一个多核CPU,其中一些子任务在同一个核心上并发运行,而其他子任务在不同的核心上并行运行。
    在这里插入图片描述

在上述示例中,一个单一任务被分成4个子任务,这些子任务被分配到2个CPU核心上进行并行执行。这些子任务由多个线程执行。一些线程在同一个CPU核心上并发运行,而其他线程在不同的CPU核心上并行运行。

如果每个子任务都由其自己的线程在专用CPU上执行(例如,4个线程在4个CPU上),任务执行就会完全并行,不涉及并发

通常很难将一个任务精确地分成与CPU数量相同的子任务。相反,任务通常被分成与问题的结构和可用的CPU核心数量自然匹配的若干子任务。

总结

在这里插入图片描述


http://www.ppmy.cn/news/1576914.html

相关文章

FPGA学习(一)——DE2-115开发板编程入级

FPGA学习(一)——DE2-115开发板编程入级 一、实验目的 通过 1 位全加器的详细设计,深入掌握原理图输入以及 Verilog 的两种设计方法,熟悉 Quartus II 13.0 软件的使用流程,以及在 Intel DE2-115 开发板上的硬件测试过…

用CLI操作MySQL 92数据库的命令

打开CLI: 输入数据库root密码: 注意:root密码在安装MySQL数据库时创建。需要记住。 查看数据库,可以参考库-表-列的顺序,先查看数据库库: show databases;再查看数据cfriends_db数据库中的数据…

HarmonyOS学习第12天:解锁表格布局的奥秘

表格布局初相识 不知不觉,我们在 HarmonyOS 的学习旅程中已经走到了第 12 天。在之前的学习里,我们逐步掌握了 HarmonyOS 开发的各种基础与核心技能,比如组件的基本使用、布局的初步搭建等,这些知识就像一块块基石,为我…

微软官宣5 月 5 日关闭 Skype,赢者通吃法则依然有效

微软官宣:5月5日关闭Skype 近日,微软公司宣布了一项重要决定:旗下广受欢迎的全球网络通话服务Skype将于2025年5月5日正式关闭。这一消息在全球范围内引发了广泛关注与讨论。 从Skype的崛起来看,它凭借免费拨打电话(尤…

shell脚本编程实践第6天

1 正则表达式 1.1 进阶知识 1.1.1 扩展符号 学习目标 这一节,我们从 基础知识、简单实践、小结 三个方面来学习 基础知识 简介 字母模式匹配[:alnum:] 字母和数字[:alpha:] 代表任何英文大小写字符,亦即 A-Z, a-z[:lower:] 小写字母,示例:[[:lowe…

DRMPlaneType里有VIG, DMA,和RGB三种类型,这是不是说明DRMPlane就是代表DPU里的Pipeline

DRMPlane 代表了 DPU(Display Processing Unit) 里的 Pipeline(数据通路),不同的 DRMPlaneType 对应 DPU 内部的不同 渲染/合成管线。 📌 DRMPlaneType 与 DPU Pipeline 的关系 在 高通(Qualco…

软考中级-数据库-3.4 数据结构-图

图的定义 一个图G(Graph)是由两个集合:V和E所组成的,V是有限的非空顶点(Vertex)集合,E是用顶点表示的边(Edge)集合,图G的顶点集和边集分别记为V(G)和E(G),而将图G记作G(V,E)。可以看出,一个顶点集合与连接这…

腾讯--后台开发实习生一面的算法真题整理(2025年3月4日)

面经小记: 资料来源于网络收集。 腾讯实习基地Java后端一面准备: 算法模式:ACM模式卡码网ACM模式练习 需要独立完成完整代码,包括方法类的创建、功能函数和主函数,大致给出模板如下: public class Mai…