http://showmecode.cn/links/book http://showmecode.cn/links/book Table of Contents Introduction 1.1 前言 1.2 关于封面 1.3 关于本书 1.4 第1章 你好,C++的并发世界 1.5 第2章 线程管理 1.6 第3章 线程间共享数据 1.7 第4章 同步并发操作 1.8 第5章 C++内存模型和原子类型操作 1.9 第6章 基于锁的并发数据结构设计 1.10 第7章 无锁并发数据结构设计 1.11 第8章 并发代码设计 1.12 第9章 高级线程管理 1.13 第10章 多线程程序的测试和调试 1.14 附录A C++11语言特性简明参考(部分) 1.15 附录B 并发库简要对比 1.16 附录C 消息传递框架与完整的ATM示例 1.17 附录D C++线程类库参考 1.18 资源 1.19 2 http://showmecode.cn/links/book Introduction C++ Concurrency In Action Practical Multithreading 作者:Anthony Williams 本书概述 作为对《C++ Concurrency in Action》的中文翻译。 本书是基于C++11新标准的并发和多线程编程深度指南。 从std::thread、std::mutex、std::future和std::async等基础类的使用,到内存模型和原子操 作、基于锁和无锁数据结构的构建,再扩展到并行算法、线程管理,最后还介绍了多线程代 码的测试工作。 本书的附录部分还对C++11新语言特性中与多线程相关的项目进行了简要的介绍,并提供了 C++11线程库的完整参考。 本书适合于需要深入了解C++多线程开发的读者,以及使用C++进行各类软件开发的开发人 员、测试人员。 对于使用第三方线程库的读者,也可以从本书后面的章节中了解到相关的指引和技巧。 同时,本书还可以作为C++11线程库的参考工具书。 书与作者 Anthony Williams是BSI C++小组的成员,拥有10多年C++应用经验。 如今多核芯处理器使用的越来越普遍。C++11标准支持多线程,这就需要程序员掌握多线程编 程的原则、技术和新语言中的并发特性,确保自己处于时代前沿。 无论你的C++技术如何,本书都会指引你使用C++11写出健壮和优雅的多线程应用。本书将会 探讨线程的内存模型,新的多线程库,启动线程和同步工具。在这个过程中,我们会了解并 发程序中较为棘手的一些问题。 内容的大体结构: C++11编程 3 http://showmecode.cn/links/book Introduction 多核芯编程 简单例子用于学习,复杂例子用于实践 本书是为C++程序员所写,同僚中可能有人对并发还没什么了解,估计也有人已经使用其他语 言、API或平台写过多线程程序。不过,在看本书的时候,你们都在同一“起跑线”上。 访问本书论坛曼宁-C++ Concurrency in Action可获取免费电子书。 本书相关 github 翻译地址:https://github.com/xiaoweiChen/Cpp_Concurrency_In_Action gitbook 在线阅读:http://chenxiaowei.gitbooks.io/cpp_concurrency_in_action/ 书中源码:https://github.com/bsmr-c-cpp/Cpp-Concurrency-in-Action 学习C++11/14: http://www.bogotobogo.com/cplusplus/C11 4 http://showmecode.cn/links/book 前言 前言 我与多线程的邂逅是在毕业后的第一份工作中。那时我们正在写一个填充数据库的程序。不 过,需要处理的数据量很大,每条记录都是独立的,并且需要在插入数据库之前,对数据量 进行合理分配。为了充分利用10核UltraSPARC CPU(Ultra Scalable Processor ARChitecture,终极可扩充处理器架构(大端)),我们使用了多线程,每个线程处理自己所要 记录的数据。我们使用C++和POSIX线程库完成编码,也犯了一些错误——当时,多线程对 于我们来说是一个新事物——不过,最后我们还是完成了。也是在做这个项目的时候,我开 始注意C++标准委员会和刚刚发布的C++标准。 我对多线程和并发有着浓厚的兴趣。虽然,别人觉得多线程和并发难用、复杂,还会让代码 出现各种各样的问题,不过,在我看来这是一种强有力的工具,能让你充分使用硬件资源, 让你的程序运行的更快。 从那以后,我开始使用多线程和并发在单核机器上对应用性能和响应时间进行改善。这里, 多线程可以帮助你隐藏一些耗时的操作,比如I/O操作。同时,我也开始学习在操作系统级别 上使用多线程,并且了解Intel CPU如何处理任务切换。 同时,对C++的兴趣让我与ACCU有了联系,之后是BSI(英国标准委员会)中的C++标准委员 会,还有Boost。也是因为兴趣的原因,我参与了Boost线程库的初期开发工作,虽然初期版 本已经被开发者们放弃,但是我抓住了这次机会。直到现在,我依然是Boost线程库的主要开 发者和维护者。 作为C++标准委员会的一员,对现有标准的缺陷的和不足进行改善,并为新标准提出建议(新 标准命名为C++0x是希望它能在2009年发布,不过最后因为2011年才发布,所以官方命名为 C++11)。我也参与很多BSI的工作,并且我也为自己的建议起草建议书。当委员会将多线程提 上C++标准的日程时,我高兴的差点飞起来,因为我起草及合著的多线程和并发相关的草案, 将会成为新标uij准的一部分。新标准将我(计算机相关)的两大兴趣爱好——C++和多线程—— 结合起来,想想还有点小激动。 本书旨在教会其他C++开发者如何安全、高效的使用C++11线程库。我对C++和多线程的热 爱,希望你也能感受的到。 5 http://showmecode.cn/links/book 关于封面 封面图片介绍 本书的封面图片的标题是“日本女性的着装”(Habit of a Lady of Japan)。这张图源自Thomas Jefferys所著的《不同民族服饰的收藏》(Collection of the Dress of Different Nations)[1]第四 卷(大概在1757年到1772年间出版)。Thomas收集的服饰包罗万象,他的绘画优美而又细腻, 对欧洲戏剧服装设计产生了长达200多年的影响。服饰中包含着一个文明的过去和现在,伦敦 剧院的观众通过不同的服饰对不同时代中各个国家的习俗。 在过去的250多年里,着装风格开始发生了变化,各个国家和区域之间巨大的差异逐渐消失。 现在已经很难分辨出不同洲不同地区的人们的着装差异。或许,我们放弃了这种文化上的差 异,得到的却是更加丰富多彩的个人生活——或者说是一种更加多样有趣、更快节奏的科技 生活。 在各种计算机图书铺天盖地、让人难以分辨的时代,Manning出版社正是为了赞美计算机行业 中的创新性和开拓性,才选用了这个重现两个世纪之前丰富多样的地域风情的图片。 【1】 《iPhone与iPad开发实战》使用了书中的另一张图片,感兴趣的同学可以去图灵社区 进行试读(只免费提供第1章内容),本章翻译复制了这本书翻译的部分内容 6 http://showmecode.cn/links/book 关于本书 关于这本书 本书是并发和多线程机制指导书籍(基于C++11标准)。从最基本的 std::thread 和 的使用,到复杂的原子操作和内存模型。 std::mutex std::async 路线图 前4章,介绍了标准库提供的各种库工具,展示了使用方法。 第5章,涵盖了底层内存模型和原子操作的实际情况,包括原子操作如何对执行顺序进行限制 (这章标志着介绍部分的结束)。 第6、7章,开始讨论进阶级主题,如何使用基本工具去构建复杂的数据结构——第6章是基于 锁的数据结构,第7章是无锁数据结构。 第8章,对设计多线程代码给了一些指导意见,覆盖了性能问题和并行算法。 第9章,线程管理——线程池,工作队列和中断操作。 第10章,测试和调试——bug类型,定位Bug的技巧,以及如何进行测试等等。 附录,包括新的语言特性的简要描述,主要是与多线程相关的特性,以及在第4章中提到的消 息传递库的实现细节和C++11线程库的完整的参考。 谁应该读这本书 如果你正在用C++写一个多线程程序,你应该阅读本书。如果你正在使用C++标准库中新的多 线程工具,你可以从本书中得到一些指导意见。如果你正在使用其他线程库,后面章节里的 建议和技术指导也很值得一看。 阅读本书的前提是,你已经有了一个较好的C++基础知识;虽然,关于多线程编程的知识或者 经验是不必须的,不过这些经验可能有用。 如何使用这本书 如果从来没有写过多线程代码,我建议你从头到尾阅读本书;不过,可以跳过第5章中的较为 细节的部分。第7章内容依赖于第5章中的内容,因此,如果跳过了第5章,应该保证在读第7 章时,已经读过第5章。 如果没有用过C++11的工具,为了跟上这本书的进度,可以先阅读一下附录。新工具的使用在 文本中已经标注出来,不过,当遇到一些没见过的工具时,可以随时回看附录。 7 http://showmecode.cn/links/book 关于本书 即使有不同环境下写多线程代码的经验,开始的章节仍有必要浏览一下,这样就能清楚的知 道,你所熟知的工具在新的C++标准中对应了哪些工具。如果使用原子变量去做一些底层工 作,第5章必须阅读。第8章,有关C++多线程的异常和安全性内容很值得一看。如果你对某 些关键词比较感兴趣,索引和目录能够帮你快速找到相关的内容。 你可能喜欢回顾主要的章节,并使用一个自己的方式阅读示例代码。虽然你已经了解C++线程 库,但附录D还是很有用。例如,查找每个类和函数的细节。 代码公约和下载 为了区分普通文本,列表中的所有代码和文本中的像这样固定宽度的字体。代码注释伴随着 许多列表,重要概念高亮显示。在某些情况下,你可以通过页下给出的快捷链接进行查阅。 本书所有实例的源代码,可在出版商的网站上进行下载: www.manning.com/cplusplusconcurrencyinaction。 软件需求 使用书中的代码,可能需要一个较新的C++编译器(要支持C++11语言的特性(见附录A)),还需 要C++支持标准线程库。 写本书的时候,g++是唯一实现标准线程库的编译器(尽管Microsoft Visual Studio 2011 preview中也有实现)。g++4.3发布时添加了线程库,并且在随后的发布版本中进行扩展。 g++4.3也支持部分C++11语言特性,更多特性的支持在后续发布版本中也有添加。更多细节 请参考g++ C++11的状态页面[1]。 Microsoft Visual Studio 2010支持部分C++11特性,例如:右值引用和lambda函数,但是没有 实现线程库。 我的公司Software Solutions Ltd,销售C++11标准线程库的完整实现,其可以使用在 Microsoft Visual Studio 2005, Microsoft Visual Studio 2008, Microsoft Visual Studio 2010, 以及各种g++版本上[2]。这个线程库也可以用来测试本书中的例子。 Boost线程库[3]提供的API,以及可移植到多个平台。本书中的大多数例子将 替换 std:: 为 ,再 引用适当的头文件,就能使用Boost线程库来运行。还有部分工具 boost:: #include 还不支持(例如 )或在Boost线程库中有着不同名字(例 std::async 如: )。 boost::unique_future 作者在线 8 http://showmecode.cn/links/book 关于本书 购买C++ Concurrency in Action就能访问曼宁(Manning Publications)的私人网络论坛,在那 里可以对本书做一些评论,问一些技术问题,获得作者或其他读者的帮助。为了能够访问论 坛和订阅,在浏览器地址中输入www.manning.com/CPlusPlusConcurrencyinAction后,页面 将告诉你如何注册之后访问论坛,你能获得什么样的帮助,还有论坛中的一些规则。 曼宁保证为本书的读者提供互相交流,以及和作者交流的场所。虽然曼宁自愿维护本书的论 坛,但不保证这样的场所不会收取任何的费用。所以,建议你可以尝试提一些有挑战性的问 题给作者,免得这样的地方白白浪费。 在本书印刷时,就可以通过Internet访问作者的在线论坛和之前讨论的文字记录。 【1】GNU Compiler Collection C++0x/C++11 status page, http://gcc.gnu.org/projects/cxx0x.html. 【2】The implementation of the C++ Standard Thread Library, just::thread http://www.stdthread.co.uk. 【3】The Boost C++ library collection, http://www.boost.org. 9 http://showmecode.cn/links/book 第1章 你好,C++的并发世界 第1章 你好,C++的并发世界! 本章主要内容 何谓并发和多线程 应用程序为什么要使用并发和多线程 C++的并发史 一个简单的C++多线程程序 令C++用户振奋的时刻到了。距初始的C++标准(1998年)发布13年后,C++标准委员会给 语言本身,以及标准库,带来了一次重大的变革。 新C++标准(也被称为C++11或C++0x)在2011年发布,带来一系列的变革让C++编程更加简 单和高效。 其中一个最重要的新特性就是对多线程的支持。 C++标准第一次承认多线程在语言中的存在,并在标准库中为多线程提供组件。这意味着使用 C++编写与平台无关的多线程程序成为可能,也为可移植性提供了强有力的保证。与此同时, 程序员们为提高应用的性能,对并发的关注也是与日俱增,特别在多线程编程方面。 本书是介绍如何使用C++11多线程来编写并发程序,及相关的语言特性和库工具(library facilities)。本书以“解释并发和多线程的含义,为什么要使用并发”作为起始点,在对“什么情况 下不使用并发”进行阐述之后,将对C++支持的并发方式进行概述;最后,以一个简单的 C++并发实例结束这一章。资深的多线程开发人员可以跳过前面的小节。在后面的几个章节 中,会有更多的例子,以便大家对库工具(library facilities)进行更加深入的了解。本书最后, 将会给出所有多线程与并发相关的C++标准库工具的全面参考。 问题来了,何谓并发(concurrency)?何谓多线程(multithreading)? 1.1 何谓并发 最简单和最基本的并发,是指两个或更多独立的活动同时发生。 并发在生活中随处可见,我们可以一边走路一边说话,也可以两只手同时作不同的动作,还 有我们每个人都过着相互独立的生活——当我在游泳的时候,你可以看球赛,等等。 1.1.1 计算机系统中的并发 计算机领域的并发指的是在单个系统里同时执行多个独立的任务,而非顺序的进行一些活 动。 10