天天看点

C++11 并发编程指南——前言

并发(concurrency)在我们的现实世界中随处可见,以至于我们常常忽略了它的存在,比方说你在工作(假设你是一名程序员,你的工作就是编程)的时候也可以听听自己喜欢的音乐,并且你的耳朵并不会因为手头的工作而忽略了声音的存在(当然,除非你自己有意的去忽略它,但你还是能够听得见声音,只是你的大脑可能不会去感受音乐的节奏),此时你的大脑既要控制你的双手敲击键盘,也要控制你的耳朵去感受音乐。因此,在一定程度上,你的大脑就在并发地处理不同的事情,并且每个时刻都可能会侧重处理某件事情,比如某个时刻音乐达到高潮并且是你喜欢的旋律,你可能会放慢或者停止手边的工作,但在另外一个时刻你正在编写关键代码,需要全神贯注来避免 bug 的出现,你可能会把声音调小一点或者干脆摘掉耳机。所以,我们的大脑就在并发地指导我们完成各种任务,或者换一种说法,我们需要处理的任务并发地征用我们的大脑,大脑就相当于计算机的 cpu,而待处理的任务就相当于计算机程序(更确切地说应该是进程或线程等执行实体)。

不过在现实世界中,我们并不会严格定义什么是并发。而在计算机程序世界中,为了编写高性能的代码,我们应该理解什么是并发,并发的基本特性是什么,哪些问题可以使用并发编程来(高效地)解决,哪些情况下又应该尽量避免使用并发编程,我们在使用并发编程时需要注意一些什么问题,本章的将会给大家介绍并发的基本概念,带领大家学习并发编程的基本技巧。

与并发相近的另一个概念是并行(parallel)。和并发所描述的情况一样,并行也是指两个或多个任务被同时执行。但是严格来讲,并发和并行的概念并是不等同的,两者存在很大的差别。下面我们来看看计算机科学家们是怎么区分并发和并行的。

erlang 是一种通用的并行程序设计语言,在并行、分布式和容错等方面表现优异。下面是 erlang 官方的介绍:

erlang is a programming language used to build massively scalable soft real-time systems with requirements on high availability. erlang’s runtime system has built-in support for concurrency, distribution and fault tolerance.
C++11 并发编程指南——前言

直观来讲,并发是两个等待队列中的人同时去竞争一台咖啡机(当然,人是有理性懂礼貌的动物(也不排除某些很霸道的人插队的可能),两队列中的排队者也可能约定交替使用咖啡机,也可能是大家同时竞争咖啡机,谁先竞争到咖啡机谁使用,不过后一种的方法可能引发冲突,因为两个队列里面排在队列首位的人可能同时使用咖啡机),每个等待者在使用咖啡机之前不仅需要知道排在他前面那个人是否已经使用完了咖啡机,还需知道另一个队列中排在首位的人是否也正准备使用咖啡机;而并行是每个队列拥有自己的咖啡机,两个队列之间并没有竞争的关系,队列中的某个排队者只需等待队列前面的人使用完咖啡机,然后再轮到自己使用咖啡机。

因此,并发意味着多个执行实体(比方说上面例子中的人)可能需要竞争资源(咖啡机),因此就不可避免带来竞争和同步的问题;而并行则是不同的执行实体拥有各自的资源,相互之间可能互不干扰。

go 是一门新兴的编程语言,go 官方对其介绍如下:

the go programming language is an open source project to make programmers more productive.go is expressive, concise, clean, and efficient. its concurrency mechanisms make it easy to write programs that get the most out of multicore and networked machines.
concurrency is about dealing with lots of things at once. parallelism is about doing lots of things at once.

前者是关于程序结构的,而后者是关于程序执行的。rob 认为:

concurrency provides a way to structure a solution to solve a problem that may (but not necessarily) be parallelizable.
C++11 并发编程指南——前言

并行(parallelism)指两个或两个以上事件或活动在同一时刻发生。在多道程序环境下,并行性使多个程序同一时刻可在不同cpu上同时执行,如下图所示:

C++11 并发编程指南——前言

因此,该文认为并发与并行的区别是:并发是一个处理器同时处理多个任务,而并行多个处理器或者是多核的处理器同时处理多个不同的任务。前者是逻辑上的同时发生(simultaneous),而后者是物理上的同时发生。而两者的联系是:并行的事件或活动一定是并发的,但反之并发的事件或活动未必是并行的。并行性是并发性的特例,而并发性是并行性的扩展(个人不赞同此观点)。

本文主要讲了什么是并发以及并发和并行的联系和区别。总得来说,joe armstrong 的观点通俗易懂,rob pike 有关并发和并行的的观点也很有意思。而关于并发和并行具体的差异,本文最后介绍了一种教科书式的解释。读者可以根据自己的理解来选择认同上述某一种或几种观点。