G.MTH.LCK.03 尽量避免直接使用标准库 std::sync
模块中的同步原语,替换为 parking_lot
【级别】 建议
【描述】
尽量避免对标准库 std::sync
模块中锁同步原语的使用,建议使用 parking_lot
的实现。
【反例】
来源于 std标准库文档
#![allow(unused)] fn main() { // 不符合 use std::sync::{Arc, Mutex}; use std::thread; use std::sync::mpsc::channel; const N: usize = 10; let data = Arc::new(Mutex::new(0)); let (tx, rx) = channel(); for _ in 0..N { let (data, tx) = (Arc::clone(&data), tx.clone()); thread::spawn(move || { let mut data = data.lock().unwrap(); *data += 1; if *data == N { tx.send(()).unwrap(); } }); } rx.recv().unwrap(); }
【正例】
例子来源于 parking_lot 文档
相比std::sync::Mutex
,使用 parking_lot::Mutex
能实现'无中毒',锁在 panic 时正常释放,更少的空间占用等优势。
#![allow(unused)] fn main() { // 符合 use parking_lot::Mutex; use std::sync::{Arc, mpsc::channel}; use std::thread; const N: usize = 10; let data = Arc::new(Mutex::new(0)); let (tx, rx) = channel(); for _ in 0..10 { let (data, tx) = (Arc::clone(&data), tx.clone()); thread::spawn(move || { let mut data = data.lock(); *data += 1; if *data == N { tx.send(()).unwrap(); } }); } rx.recv().unwrap(); }