本文的大部分内容都隐含集中在顺序程序:程序在单一上下文中。在第 6 章我们看到,顺序是命令式程序的基础。声明式程序中也隐含了这种前提,因为函数式和逻辑语言通常都包含了命令式语言的特性,部分是因为人们倾向于使用命令性表达,即使声明式语言不要求这样。
想法,程序如果不止有一个执行上下文,就称为并行的 -- 超过一个线程。并发有三个重要动机:
- 捕获问题的逻辑结构。很多程序,尤其是服务器和图形程序,必须同时执行大量独立“任务”。最简单符合逻辑的方法是每个线程执行一个任务。我们已经在 9.5 聊 coroutine 和 9.6 聊事件时提到过多线程,在 13.1.1 中将会重新讨论
- 利用硬件并行,为了速度。长期以来,高端服务器和超级计算机的多处理器(或者多核)开始在桌面计算机,笔记本,和手机中流行。为了高效使用多核,程序需要以并发的方式编写。
- 处理物理世界的变化【译者注:不好信雅达的翻译】。运行在网络上或者本地机器组的应用天生就是并发的。很多嵌入式应用也是如此:现代汽车的控制系统可能需要跨越数十个处理器。
通常我们使用 concurrent 来表征同时运行两个或者更多任务的系统。在这个定义下,coroutines 不是 concurrent, 因为在给定的时间,只有一个在运行。concurrent 系统是 parallel 的如果物理上同时运行多个任务;这要求多个处理器。区别是纯粹的实现和性能问题:从语义角度来看,在无法预测的时间之间切换任务的系统的真实 parallelism 和 quasiparallelism 并没有区别。如果处理器是物理分离的,parallel 系统就是分布式的。根据这些定义,concurrent 满足三种动机,parallel 满足第二和第三点,distributed 只满足第三点。
本章关注 concurrent 和 parallelism。2005年以来,随着多核处理器的流行,parallelism 成为被关心的问题。我们很少谈到 distribution。虽然语言为分布式计算设计,大多数分布式系统是在联网的处理器中执行单独的程序,使用消息系统进行通信。
我们开始于现代计算中可能出现的 parallelism 方法概述。我们的概述会涉及 concurrency 的动机,race 的概念(是并发程序中复杂度的来源)。我们简要介绍现代多核和多处理器。在 13.2 中我们考虑两种并发模型,shared-memory model 和 message-passing model,语言和库的实现。基于 coroutine,我们解释语言或者库如何创建和调度线程。13.3 集中于 shared-memory 同步的底层机制。13.4 扩展到语言结构层面的讨论。message-passing model 在 13.5 中讨论(实际上更多的在扩展文档中)