新書推薦:
《
你漏财了:9种逆向思维算清人生这本账
》
售價:NT$
254.0
《
我们终将老去:认识生命的第二阶段(比利时的“理查德·道金斯”,一位行为生物学家的老年有用论
》
售價:NT$
418.0
《
祛魅:对世界祛魅是一个人变强的开始
》
售價:NT$
286.0
《
家族财富传承
》
售價:NT$
704.0
《
谁是窃书之人 日本文坛新锐作家深绿野分著 无限流×悬疑×幻想小说
》
售價:NT$
254.0
《
一个经济杀手的自白 第3版
》
售價:NT$
505.0
《
8秒按压告别疼痛
》
售價:NT$
398.0
《
津巴多时间心理学:挣脱束缚、改写命运的6种时间观
》
售價:NT$
352.0
編輯推薦:
编辑推荐
Rust编程语言非常适合并发编程,并且其生态系统中有许多库包含大量并发数据结构、锁等。但正确实现这些结构可能会很困难。即使在使用最z广泛的库中,内存顺序错误也并不少见。
在这本非常实用的书中,Rust库团队负责人Mara Bos帮助各个级别的Rust程序员清晰地理解底层并发性。你将学习有关原子操作和内存顺序的一切,以及它们如何与基本操作系统API结合使用来构建诸如互斥锁和条件变量之类的常见原语。完成后,你将牢固掌握Rust的内存模型、处理器以及操作系统是如何相互配合的。
专家推荐
“这本书太棒了!它正是我想要在The Rustonomicon里涵盖的并发内容,但比我做梦都要好得多。在所有正确的地方都非常详尽。Mara写完这本书之后应该好好休息一下。”
——Aria Beingessner
The Rustonomicon的作者
內容簡介:
通过本书,你将学到:Rust的类型系统和正确的并发编程如何非常好地配合。有关互斥锁、条件变量、原子操作和内存顺序的一切。在英特尔和ARM处理器上进行原子操作时会发生什么情况。锁是如何借助操作系统的支持来实现的。如何编写包含并发、原子操作和锁的正确代码。如何正确构建自己的锁和同步原语。
關於作者:
Mara Bos维护着Rust标准库,并用Rust构建实时控制系统。作为Rust库团队的负责人,她熟知该语言和标准库的方方面面。此外,作为Fusion Engineering 的创始人兼首席技术官,她多年来一直致力于并发实时系统的工作。维护Rust 生态系统中最z常用的库,并每天致力于安全相关系统的工作,使她具备了丰富的实践经验,既能理解理论又能将其付诸实践。
目錄 :
序 1
前言 3
第1 章 Rust 并发基础 9
1.1 Rust 中的线程 .10
1.2 作用域线程 14
1.3 共享所有权和引用计数 .17
1.3.1 静态对象 .17
1.3.2 泄漏 17
1.3.3 引用计数 .18
1.4 借用和数据竞争 21
1.5 内部可变性 23
1.5.1 Cell .24
1.5.2 RefCell .25
1.5.3 Mutex 和RwLock 26
1.5.4 原子类型 .26
1.5.5 UnsafeCell 27
1.6 线程安全性:Send 和Sync .27
1.7 锁:互斥锁和读写锁 30
1.7.1 Rust 的互斥锁 30
1.7.2 锁中毒 33
1.7.3 读写锁 35
1.8 等待:线程停放与条件变量 37
1.8.1 线程停放 .37
1.8.2 条件变量 .40
1.9 总结 .42
第2 章 原子性 45
2.1 原子加载和存储操作 46
2.1.1 示例:停止标志 47
2.1.2 示例:进度报告 48
2.1.3 示例:延迟初始化 .50
2.2 获取—修改操作 52
2.2.1 示例:多线程进度报告 53
2.2.2 示例:统计 55
2.2.3 示例:ID 分配 .57
2.3 比较—交换操作 59
2.3.1 示例:无溢出的ID 分配 .61
2.3.2 示例:延迟一次性初始化 62
2.4 总结 .64
第3 章 内存顺序 67
3.1 重排与优化 67
3.2 内存模型69
3.3 happens-before 关系 70
3.4 宽松顺序73
3.5 释放和获取顺序 76
3.5.1 例子:锁定 80
3.5.2 示例:通过间接方式实现延迟初始化 .82
3.6 消费顺序85
3.7 顺序一致性顺序 87
3.8 栅栏 .88
3.9 常见误解93
3.10 总结 95
第4 章 构建我们自己的自旋锁 97
4.1 最简实现98
4.2 不安全的自旋锁 .100
4.3 使用锁卫士的安全接口 103
4.4 总结 106
第5 章 构建我们自己的通道 109
5.1 一个基于互斥锁的简单通道 .109
5.2 一个不安全的一次性通道 . 111
5.3 通过运行时检查提高安全性 . 115
5.4 通过类型系统提高安全性 .120
5.5 通过借用避免分配 .125
5.6 阻塞 129
5.7 总结 132
第6 章 构建我们自己的Arc 135
6.1 基础引用计数 135
6.1.1 测测它 140
6.1.2 修改 .141
6.2 弱指针 .143
6.3 优化 150
6.4 总结 158
第7 章 理解处理器 161
7.1 处理器指令 162
7.1.1 加载和存储 .166
7.1.2 Read-Modify-Write 操作 168
7.1.3 Load-Linked 指令和Store-Conditional 指令 172
7.2 缓存 177
7.2.1 缓存一致性 .178
7.2.2 对性能的影响 .180
7.3 重排 186
7.4 内存顺序.188
7.4.1 x86-64:强内存序 189
7.4.2 ARM64:弱内存序 .191
7.4.3 一个实验 194
7.4.4 内存屏障 196
7.5 总结 198
第8 章 操作系统原语 201
8.1 与内核交互 201
8.2 POSIX .203
8.3 Linux 207
8.3.1 Futex 208
8.3.2 Futex 操作 211
8.3.3 优先级继承Futex 操作 .215
8.4 macOS .216
8.5 Windows .217
8.5.1 重量级内核对象 218
8.5.2 轻量级对象 .218
8.5.3 基于地址的等待 220
8.6 总结 221
第9 章 构建我们自己的锁 223
9.1 Mutex 225
9.1.1 避免系统调用 .229
9.1.2 进一步优化 .231
9.1.3 基准测试 234
9.2 条件变量.237
9.2.1 避免系统调用 .243
9.2.2 避免错误唤醒 .245
9.3 读写锁 .248
9.3.1 避免忙循环的写入者252
9.3.2 避免写入者饥饿 255
9.4 总结 258
第10 章 想法和灵感 . 261
10.1 信号量 261
10.2 RCU 262
10.3 无锁链表 264
10.4 队列锁 265
10.5 停车位锁 266
10.6 序列锁 267
10.7 教学材料 268
內容試閱 :
前言Rust 大大降低了系统编程的理解难度,并且一直在这个领域发力。然而,关于底层并发的问题,如原子操作和内存顺序,仍然常被认为是相当神秘的领域,最好留给为数不多的专业人士来处理。在过去的几年里,我一直在使用Rust 进行实时控制系统和标准库的开发。我发现,大部分现有关于原子操作及其相关主题的资源仅可覆盖我所寻找的一部分。许多资源完全专注于使用C 和C ,这让人很难和Rust 的内存与线程安全以及类型系统建立起联系。那些涉及像C 内存模型这样的抽象理论细节的资源,往往也只是含糊其词地解释这些理论与实际硬件之间的关系,尽管有很多资源深入地解读硬件的各个细节,如处理器指令和缓存一致性,但要想形成全面的理解,通常需要从各种不同的地方收集零散信息。这本书试图将所有相关信息整合到一处,相互关联起来,提供你需要构建自己的正确、安全和符合人体工程学的并发基础设施的一切。同时,你还将对底层硬件和操作系统的角色有足够的理解,能够进行设计决策和基础优化的权衡。谁应该阅读本书这本书的主要读者是想要更多了解底层并发的Rust 开发者。此外,这本书也适合那些尚不太熟悉Rust,但想从Rust 角度了解底层并发的人。本书假定你已经掌握了Rust 的基础知识,安装了最新的Rust 编译器,并知道如何使用cargo 来编译和运行Rust 代码。与并发相关的重要Rust 概念会在适当的地方进行简要解释,因此,你无需预先具有Rust 并发知识。章节概览本书共有10 章。以下是每章的内容概述和预期收获:第1 章,Rust 并发基础本章介绍了Rust 并发基础所需的所有工具和概念,例如线程、互斥锁、线程安全、共享和独占引用、内部可变性等,这些是本书后续章节的基础。对于已经熟悉这些概念且有Rust 经验的程序员来说,本章可以作为一个快速复习。对于那些从其他语言中了解这些概念但还不太熟悉Rust 的人来说,本章将迅速为你填补可能需要了解的Rust 相关知识。第2 章,原子性在第2 章中,我们将学习Rust 的原子类型及其操作。我们从简单的加载和写入操作开始,并逐步过渡到更高级的compare-and-exchange 循环,通过几个真实世界的例子来探索每个新概念。虽然内存顺序对于每个原子操作都是相关的,但该主题我们将留到第3 章中讨论。本章仅涵盖满足宽松内存顺序的情况,因为这种情况比人们预期的更为常见。第3 章,内存顺序在学习了各种原子操作及其使用方法之后,第3 章介绍了本书最复杂的主题:内存顺序。我们将探讨内存模型的工作原理、Happens-before 关系以及如何创建它们、所有不同内存顺序的含义以及为什么顺序一致性可能并非万能的解决方案。第4 章,构建我们自己的自旋锁在学习理论之后,我们将在接下来的3 章中通过构建几个常见并发原语来进行实践。这些章节中的第一章是一个简短的章节,在其中我们实现了一个自旋锁。我们将从非常基本的版本开始,以便练习释放和获取内存顺序,并且然后探索Rust 的安全性概念,将其转化为符合Rust 人体工程学且难以误用的数据类型。第5 章,构建我们自己的通道在第5 章中,我们将从头开始实现几个一次性通道(one-shot channel)的变体,这是一种可以将数据从一个线程发送到另一个线程的原语。我们将从非常简单但完全不安全的版本开始,逐步通过几种方法来设计安全的接口,并考虑设计决策及其后果。第6 章,构建我们自己的Arc在第6 章中,我们将接受一个更具挑战性的内存顺序难题。我们将从头开始实现自己的原子引用计数。在添加了对弱指针的支持并进行性能优化后,我们的最终版本几乎与Rust的标准库中的std::sync::Arc 类型完全相同。第7 章,理解处理器第7 章是对所有底层细节的深入探讨。我们将探索在处理器级别发生了什么,最流行的两种处理器架构中原子操作背后的汇编指令长什么样,缓存是什么以及它如何影响我们的代码性能,并分析出在硬件层面上内存模型还剩下些什么。第8 章,操作系统原语在第8 章中,我们认识到有些事情需要操作系统内核的帮助,并且学习Linux、macOS 和Windows 中需要用到的功能。我们将讨论POSIX 系统上的pthreads 并发原语,了解可以使用Windows API 做什么,并学习Linux 的futex syscall 的作用。第9 章,构建我们自己的锁利用前几章学到的知识,在第9 章中,我们将从头开始构建互斥锁、条件变量和读写锁的多个实现。对于每一个实现,我们都会从最小但完整的版本开始,并尝试以各种方式进行优化。通过一些简单的基准测试,我们将发现优化并不总是能提高性能,同时讨论各种设计权衡。第10 章,想法和灵感最后一章确保你在完成本书后不会陷入虚无之中,而是留下了新知识和新技能的想法和灵感,或许能开启探索更深层次底层并发的激动人心的旅程。代码示例本书中的所有代码均使用Rust 1.66.0 版本进行编写和测试,该版本于2022 年12 月15 日发布。早期版本不包括本书中使用的所有功能。但是,后续版本应该可以正常工作。为了简洁起见,代码示例不包括use 语句,除非首次介绍标准库中的新项目。为方便起见,以下prelude 内容可用于编译本书中任何代码示例:#[allow(unused)]use std::{cell::{Cell, RefCell, UnsafeCell},collections::VecDeque,marker::PhantomData,mem::{ManuallyDrop, MaybeUninit},ops::{Deref, DerefMut},ptr::NonNull,rc::Rc,sync::{*, atomic::{*, Ordering::*}},thread::{self, Thread},};补充材料,包括所有代码示例的完整版本,请访问https://marabos.nl/atomics/。你可以将本书提供的所有示例代码用于任何目的。感谢你的署名,但这不是必须的。署名通常包括标题、作者、出版社和ISBN号码。例如:“Rust Atomics and Locks by Mara Bos (O’Reilly). Copyright 2023 Mara Bos, 978-1-098-11944-7”。排版约定本书使用以下排版约定。斜体(Italic)表示新术语、URL、电子邮件地址、文件名和文件扩展名。等宽字体(Constant width)表示程序片段,以及正文中出现的程序元素,例如变量、函数名、数据类型、语句和关键字。联系我们任何有关本书的意见或疑问,请按照以下地址联系出版社。美国:O’Reilly Media, Inc.1005 Gravenstein Highway NorthSebastopol, CA 95472中国:北京市西城区西直门南大街2 号成铭大厦C 座807 室(100035)奥莱利技术咨询(北京)有限公司勘误、示例和其他信息,请访问https://oreil.ly/rust-atomics-and-locks 获取。对于本书的评论和技术性问题,请发送电子邮件到errata@oreilly.com.cn。要了解更多O’Reilly 图书和培训的信息,请访问https://oreilly.com。我们的LinkedIn:https://linkedin.com/company/oreilly-media。我们的Twitter:https://twitter.com/oreillymedia。作者的Twitter:https://twitter.com/m_ou_se。感谢我想感谢所有参与创作这本书的人。许多人提供了支持和有用的意见,这对我非常有帮助。特别是,我要感谢Amanieu d’Antras、Aria Beingessner、Paul McKenney、Carol Nichols 和Miguel Raz Guzmán Macedo 在初稿中提供的宝贵而深思熟虑的反馈。我还要感谢OReilly 的所有人,尤其是我的编辑Shira Evans 和Zan McQuade,他们无穷无尽地热情支持着我。