请说明在 Rust 中,为了在多线程间安全地共享可变数据,Arc 与 Mutex 的组合使用方式是什么?
考察说明
考察对 Rust 并发原语 Arc 与 Mutex 的理解,以及如何利用它们实现线程间共享可变数据。
回答思路
- 【回答框架 1】Arc 是原子引用计数智能指针,允许多个线程共享同一数据的所有权,而 Mutex 提供互斥锁,确保同一时刻只有一个线程能访问数据,从而避免数据竞争。
- 【回答框架 2】通常将需要共享的可变数据用 Mutex 包裹,然后放入 Arc 中,通过 Arc 的 clone 方法将引用计数增加并传递给多个线程,线程通过 lock 方法获取 Mutex 的内部可变访问权。
- 【回答框架 3】使用 Mutex 时需注意锁的粒度,避免持有锁的时间过长,防止死锁。同时,lock 返回的 MutexGuard 在作用域结束时自动释放锁。
- 【回答框架 4】Rust 的所有权系统保证了线程安全:Arc 实现 Send 和 Sync,Mutex 也实现了这些 trait,因此可以安全地在多线程间共享。
- 【回答框架 5】对于只读共享数据,可以直接使用 Arc,而不需要 Mutex;当需要修改时,才需要 Mutex 或 RwLock 等同步原语。
- 【关键点 1】Arc 提供原子引用计数,使数据可以多线程共享所有权;Mutex 提供互斥访问。
- 【关键点 2】组合方式:将数据用 Mutex 包裹,再放入 Arc,通过 clone 增加引用计数传给线程。
- 【关键点 3】访问时必须调用 lock() 获取锁,操作完成后自动释放。
- 【关键点 4】如果数据是只读的,只需 Arc 即可,无需 Mutex。
- 【易错点 1】忘记调用 lock() 而直接通过 Arc 访问数据,因为 Mutex 包裹后无法直接访问内部数据。
- 【易错点 2】持有 MutexGuard 跨作用域或调用其他需要相同锁的代码可能导致死锁。
- 【易错点 3】过度使用 Mutex 可能导致性能瓶颈,应尽量减少锁粒度。