4.7 全局变量 全局变量 在一些场景,我们可能需要全局变量来简化状态共享的代码,包括全局 ID,全局数据存储等等,下面一起来看看有哪些创建全局变量的方法。 首先,有一点可以肯定,全局变量的生命周期肯定是'static,但是不代表它需要用static来声明,例如常量、字符串字面值等无需使用static进行声明,原因是它们已经被打包到二进制可执行文件中。 下面我们从编译期初始化及运行期初始化两个类别来介绍下全 2025-02-05 rust > rust圣经 > rust高级进阶 #rust
4.6.6 基于 Send 和 Sync 的线程安全 基于 Send 和 Sync 的线程安全 为何 Rc、RefCell 和裸指针不可以在多线程间使用?如何让裸指针可以在多线程使用?我们一起来探寻下这些问题的答案。 1. 无法用于多线程的Rc 先来看一段多线程使用Rc的代码: 12345678910use std::thread;use std::rc::Rc;fn main() { let v = Rc::new(5); 2025-02-05 rust > rust圣经 > rust高级进阶 #rust
4.6.5 线程同步:Atomic 原子操作与内存顺序 线程同步:Atomic 原子类型与内存顺序 Mutex用起来简单,但是无法并发读,RwLock可以并发读,但是使用场景较为受限且性能不够,那么有没有一种全能性选手呢? 欢迎我们的Atomic闪亮登场。 从 Rust1.34 版本后,就正式支持原子类型。原子指的是一系列不可被 CPU 上下文交换的机器指令,这些指令组合在一起就形成了原子操作。在多核 CPU 下,当某个 CPU 核心开始运 2025-02-05 rust > rust圣经 > rust高级进阶 #rust
4.6.4 线程同步:锁、Condvar 和信号量 线程同步:锁、Condvar 和信号量 在多线程编程中,同步性极其的重要,当你需要同时访问一个资源、控制不同线程的执行次序时,都需要使用到同步性。 在 Rust 中有多种方式可以实现同步性。在上一节中讲到的消息传递就是同步性的一种实现方式,例如我们可以通过消息传递来控制不同线程间的执行次序。还可以使用共享内存来实现同步性,例如通过锁和原子操作等并发原语来实现多个线程同时且安全地去访问一个资源 2025-02-05 rust > rust圣经 > rust高级进阶 #rust
4.6.3 线程同步:消息传递 线程间的消息传递 在多线程间有多种方式可以共享、传递数据,最常用的方式就是通过消息传递或者将锁和Arc联合使用,而对于前者,在编程界还有一个大名鼎鼎的Actor线程模型为其背书,典型的有 Erlang 语言,还有 Go 语言中很经典的一句话: Do not communicate by sharing memory; instead, share memory by communica 2025-02-05 rust > rust圣经 > rust高级进阶 #rust
4.6.2 使用多线程 使用线程 1. 多线程编程的风险 由于多线程的代码是同时运行的,因此我们无法保证线程间的执行顺序,这会导致一些问题: 竞态条件(race conditions),多个线程以非一致性的顺序同时访问数据资源 死锁(deadlocks),两个线程都想使用某个资源,但是又都在等待对方释放资源后才能使用,结果最终都无法继续执行 一些因为多线程导致的很隐晦的 BUG,难以复现和解决 虽然 2025-02-05 rust > rust圣经 > rust高级进阶 #rust
4.6 多线程并发编程 多线程并发编程 安全和高效的处理并发是 Rust 语言的主要目标之一。随着现代处理器的核心数不断增加,并发和并行已经成为日常编程不可或缺的一部分,甚至于 Go 语言已经将并发简化到一个 go 关键字就可以。 可惜的是,在 Rust 中由于语言设计理念、安全、性能的多方面考虑,并没有采用 Go 语言大道至简的方式,而是选择了多线程与 async/await 相结合,优点是可控性更强、性 2025-02-05 rust > rust圣经 > rust高级进阶 #rust
4.5.2 结构体中的自引用 结构体自引用 1. 平平无奇的自引用 可能也有不少人第一次听说自引用结构体,那咱们先来看看它们长啥样。 123456struct SelfRef<'a> { value: String, // 该引用指向上面的value pointer_to_value: &'a str,} 以上就是一个很简单的自引用结构体,看 2025-02-05 rust > rust圣经 > rust高级进阶 #rust
4.5.1 Weak 与循环引用 Weak 与循环引用 Rust 的安全性是众所周知的,但是不代表它不会内存泄漏。一个典型的例子就是同时使用 Rc<T> 和 RefCell<T> 创建循环引用,最终这些引用的计数都无法被归零,因此 Rc<T> 拥有的值也不会被释放清理。 1. 何为循环引用 关于内存泄漏,如果你没有充足的 Rust 经验,可能都无法造出一份代码来再现它: 123 2025-02-05 rust > rust圣经 > rust高级进阶 #rust
4.5 循环引用与自引用 循环引用与自引用 实现一个链表是学习各大编程语言的常用技巧,但是在 Rust 中实现链表意味着····Hell,是的,你没看错,Welcome to hell。 链表在 Rust 中之所以这么难,完全是因为循环引用和自引用的问题引起的,这两个问题可以说综合了 Rust 的很多难点,难出了新高度,因此本书专门开辟一章,分为上下两篇,试图彻底解决这两个老大难。 本章难度较高,但是非常值得 2025-02-05 rust > rust圣经 > rust高级进阶 #rust