这一次我们来介绍一下crossbeam-util和crossbeam-queue,中的一些东西和用法。
这个是并发版的std::cell::Cell,可以对&self就起到变更内部值的效果,主要会用到下面三个方法:
use crossbeam_utils::atomic::AtomicCell; let a = AtomicCell::new(7); assert_eq!(a.load(), 7); assert_eq!(a.swap(8), 7); assert_eq!(a.load(), 8); a.store(9); assert_eq!(a.load(), 9);这个和std::sync::RwLock功能相同,不过相对来说读会更快而写更慢。大家在实际使用时可以根据业务的特点酌情选择。
use crossbeam_utils::sync::ShardedLock; let lock = ShardedLock::new(5); // 读的锁可以同时获取 { let r1 = lock.read().unwrap(); let r2 = lock.read().unwrap(); assert_eq!(*r1, 5); assert_eq!(*r2, 5); } // 写的锁只能有一个 { let mut w = lock.write().unwrap(); *w += 1; assert_eq!(*w, 6); }这个类似Golang中的sync.WaitGroup,可以用来等待几个线程的工作全部完成。
use crossbeam_utils::sync::WaitGroup; use std::thread; // 创建新的等待组 let wg = WaitGroup::new(); for _ in 0..4 { // 创建等待组的引用 let wg = wg.clone(); thread::spawn(move || { // 实际逻辑 // 解除对等待组的引用 drop(wg); }); } // 会阻塞直到所有线程完成工作 wg.wait();注意和std::sync::Barrier不同的是,WaitGroup中的线程数量是动态的。
这个和std::thread比较像,不同点在于能够支持对当前堆栈的引用。比如如果我们想要写如下的代码
let array = [1, 2, 3]; let mut guards = vec![]; for i in &array { let guard = std::thread::spawn(move || { println!("element: {}", i); }); guards.push(guard); } for guard in guards { guard.join().unwrap(); }是会报错的,因为编译器会要求&array具有'static的生命周期。但实际上因为join的部分,所以其实不会有问题,但编译器并不知道。于是就有了scope的用武之地。有了scope可以这么写:
let array = [1, 2, 3]; crossbeam::scope(|scope| { for i in &array { scope.spawn(move || { println!("element: {}", i); }); } });是不是有时候比thread要更方便一些呢~
这是并发版的队列,其实可以理解为实现了send和sync的队列。分为容量有限的ArrayQueue
use crossbeam_queue::{ArrayQueue, PushError}; let q = ArrayQueue::new(2); // 指定容量为2 assert_eq!(q.push('a'), Ok(())); assert_eq!(q.push('b'), Ok(())); assert_eq!(q.push('c'), Err(PushError('c'))); assert_eq!(q.pop(), Ok('a'));和容量无限的SegQueue
use crossbeam_queue::{PopError, SegQueue}; let q = SegQueue::new(); q.push('a'); q.push('b'); assert_eq!(q.pop(), Ok('a')); assert_eq!(q.pop(), Ok('b')); assert_eq!(q.pop(), Err(PopError));当然容量无限的代价是需要动态增加容量,这也使得SegQueue的性能会低一些。crossbeam-queue就这些内容了,是不是很简单~
其实util里面还有一些东西这里没有讲,大家可以自己去看看。这期讲的都是一些零碎的小东西。我们的crossbeam系列到这一期就结束了?吗?也许下期还有,敬请期待~