如何禁用Rust parking_lot crate中Mutex的最终公平性?
如何禁用parking_lot Mutex的公平性保障以提升性能?
我能确保rayon par_iter的线程在每批任务中仅各自锁定一次Mutex,不会出现线程饥饿问题,因此不想承担parking_lot默认公平性保障带来的约0.5毫秒开销,但仍希望保留parking_lot的其他优势。请问能否配置parking_lot的Mutex以禁用公平性保障?
以下是简化的初始化及业务代码:
use parking_lot::Mutex; use std::collections::HashSet; use rayon::prelude::*; const WIDTH: usize = 10; const HEIGHT: usize = 10; fn main() { let mut map: Vec<Vec<Mutex<HashSet<u64>>>> = Vec::with_capacity(WIDTH); for i in 0..WIDTH { map.push(Vec::with_capacity(HEIGHT)); for _ in 0..HEIGHT { map[i].push(Mutex::new(HashSet::new())); } } let mut diff: Vec<(usize, usize, u64)> = vec![(0, 0, 1), (1, 1, 2)]; // 示例数据 diff.par_iter().for_each(|(x, y, id)| { map[*x][*y].lock().insert(*id); }); }
当前这个并行实现比串行快很多,但它处于热路径中,哪怕半毫秒的性能提升对我的场景都至关重要。
已尝试的方案
我曾尝试使用ChatGPT给出的写法:
parking_lot::lock_api::Mutex<HashSet<u64, parking_lot::RawMutex>>
但这引发了编译错误。查阅文档后我了解到lock_api可能有用,但没看懂示例,不确定它能否帮我实现目标。
解决方案
parking_lot确实支持通过指定不同的原始锁类型来切换公平性:
- 默认的
parking_lot::Mutex使用的是RawMutexFair,提供最终公平性保障; RawMutex则是非公平实现,没有额外的公平性开销,同时保留parking_lot的其他性能优势(比如高效的park/unpark机制)。
正确的用法是通过lock_api模块的Mutex,结合parking_lot::RawMutex来创建非公平锁,注意泛型参数的顺序:第一个参数是被保护的数据类型,第二个是原始锁类型。
修改后的完整代码
use parking_lot::lock_api::{Mutex, RawMutex}; use std::collections::HashSet; use rayon::prelude::*; const WIDTH: usize = 10; const HEIGHT: usize = 10; fn main() { // 使用非公平Mutex:Mutex<数据类型, 原始锁类型> let mut map: Vec<Vec<Mutex<HashSet<u64>, RawMutex>>> = Vec::with_capacity(WIDTH); for i in 0..WIDTH { map.push(Vec::with_capacity(HEIGHT)); for _ in 0..HEIGHT { map[i].push(Mutex::new(HashSet::new())); } } let mut diff: Vec<(usize, usize, u64)> = vec![(0, 0, 1), (1, 1, 2)]; diff.par_iter().for_each(|(x, y, id)| { map[*x][*y].lock().insert(*id); }); }
关键说明
- 你之前的错误是把
RawMutex放到了HashSet的泛型参数里,属于类型顺序错误; Mutex<HashSet<u64>, RawMutex>才是正确的写法,明确指定用非公平的RawMutex作为底层锁实现;- 这个实现完全保留了parking_lot的高效性,同时去掉了公平性带来的额外开销,符合你的性能需求。
内容的提问来源于stack exchange,提问作者Ruddah Bagga
相关产品推荐
相关产品推荐

