一直对并发与并行的概念有点混淆,本文就来好好理解下它们。
概念
并发和并行是计算机科学中两个相关但不同的概念。首先,分别阐述下并发和并行的概念。
并发
并发(Concurrency) 涉及多个任务同时进行,这对于需要等待来自外部的数据(如数据库或网络连接)的 I/O 密集型任务特别有用。Web 服务器就是一个例子,它可以同时处理多个请求,利用并发性通过交错工作来保持系统的响应速度。通过使用协程和事件循环,程序可以在不阻塞主线程的情况下管理多个任务,从而使其能够处理更多请求并更好地扩展。 在并发系统中,多个任务可以独立启动和执行,但它们可能不会同时执行。并发的目标是通过允许系统同时处理多个请求或事件来增强系统的响应能力和吞吐量。并发通常用于通过利用现代硬件和软件架构来提高系统的效率和可扩展性,从而使开发人员能够创建能够同时处理大量任务的响应迅速的系统。 并发是一种通过有效利用可用资源来同时处理多个任务的方法。尽管它同时处理多个任务,但它在任何时间点只能执行一个非阻塞任务(执行状态)。其余任务要么处于阻塞状态,要么处于尚未开始、已完成、暂停或任何其他状态。
上面的示意图,我们似乎在同时执行多个任务,但事实上,我们是通过等待时间或阻塞状态来取消任务的优先级。这样,程序就可以在同一时间执行其他重要任务,并在得到响应后返回原处。这就是所谓的并发性。 假设所有 3 个任务都涉及一些预处理和网络调用,因此需要任意时间才能从外部系统获得响应。 运行该程序后,您将看到 task1
处于执行状态,因为它涉及一些预处理。我们还知道它涉及网络调用,因此它正在等待(阻塞状态)来自外部系统的响应。同时,task2
开始执行其预处理层,并由于网络调用而再次进入等待状态。现在有 2 个任务处于阻塞状态,因此程序开始执行 task3
及其预处理层。现在 task3
也进入了阻塞状态。一旦先前的任何阻塞状态得到响应,则其各自的任务就完成了。 由于某种原因,如果处于阻塞状态的 2 个或多个任务同时获得响应,那么程序会随机选择该任务并依次完成它。
并行
并行(Parallelism) 性涉及同时执行多个任务,这对于可分为更小的子任务的 CPU 密集型任务特别有用。例如,视频渲染程序可以利用并行性来同时渲染视频的多个帧。这有助于利用多个处理单元(例如 CPU 内核)更快、更高效地完成任务。另一个例子是交易回测程序,它使用并行性同时运行多个回测,使交易者能够快速评估各种场景并做出明智的决策。 在并行系统中,多个处理器或内核用于同时执行多个任务,通过将工作量分配给多个处理器或内核来提高单个大型任务的性能。工作负载被划分为较小的、独立的工作单元,可在不同的处理器或内核上并行执行。并行通常用于提高需要高水平计算且可以分割的任务的性能。 并行性是指在同一给定时间独立并行执行多个作业。与并发不同,它不关心任务状态,因此它会并行执行所有任务。为了执行这些独立的操作,它会消耗额外的资源。
从上面的示意图我们可以看到,所有 3 个任务都开始执行、等待并同时完成各自的任务。但总体速度而言,与并发相比,它花费的时间更少。在资源使用方面,当所有任务都处于空闲状态时,它仍然有带宽来容纳其他任务。通过并行性,我们能够更快地完成工作,但无法更好地利用资源。
使用并行性的前提,是要有一个具有多个内核的系统。
总结
综上,简单总结并发和并行,如下:
- 并发:英文单词(Concurrency),意味着使用单个资源同时处理多个任务。
- 并行:英文单词(Parallelism),意味着使用多个资源同时执行多个任务。
并发性是同时在多个任务上取得进展的能力,对于 I/O 密集型任务很有用。并行是同时执行多个任务,对于 CPU 密集型任务很有用。并发允许多个任务独立运行,而并行则在多个处理器之间分配工作负载。这两种技术可以一起使用,了解它们之间的差异对于优化软件性能和可扩展性还是非常重要的。