当前位置: 首页 > news >正文

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

并发(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核心数量自然匹配的若干子任务。

总结

在这里插入图片描述

相关文章:

  • GPPT: Graph Pre-training and Prompt Tuning to Generalize Graph Neural Networks
  • 解锁MacOS开发:环境配置与应用开发全攻略
  • vue3(笔记)2.0 生命周期函数.父子通信.ref以及模块引用.跨层级通信.v-model(基于defineModel)
  • STM32-HAL库初始化时钟
  • leetcode第77题组合
  • 【Spring Boot 应用开发】-05 命令行参数
  • c语言、c++怎么将string类型数据转成int,怎么将int转成string
  • MySQL忽略大小写问题
  • 京东一面:为什么 IDEA 建议去掉 StringBuilder,而要使用 “+” 拼接字符串?
  • 前端怎么排查幽灵依赖
  • doris:Iceberg
  • python二级考试中会考到的第三方库
  • 【大模型LLM面试合集】分布式训练_张量并行
  • 视觉Transformer(ViT)解析:它们比CNN更好吗?
  • [python] 类
  • 李国杰院士 “七问” DeepSeek:深度剖析 AI 发展新态势
  • Gin框架从入门到实战:核心用法与最佳实践
  • 深入探索像ChatGPT这样的大语言模型
  • FastGPT 引申:常见 Rerank 实现方案
  • Unity打包到webgl鼠标图标大小不正确
  • 优设/seo网站优化软件
  • 建设网站的网址/谷歌收录提交入口
  • 网站后台培训/头条号权重查询
  • 十大手游平台排行榜/内蒙古seo
  • 广州专门做网站的公司/山东百度推广总代理
  • 没有域名可以做网站/百度会员登录入口