【crossbeamシリーズ】5 crossbeam-utilとcrossbeam-queue:実用的な小物
今回はcrossbeam-utilとcrossbeam-queueの中のいくつかのものと使い方を紹介します.
これは同時版の
これは
このGolangの
これはstd::threadと似ていますが、異なる点は、現在のスタックへの参照をサポートできることです.例えば、次のようなコードを書きたい場合は
コンパイラは
時々threadよりも便利になるのではないでしょうか~
これは同時版のキューであり,実際には
容量が無限の
もちろん、容量の無限の代価は、容量を動的に増加させることであり、
実はutilの中にはまだいくつかのものがあります.ここでは話していません.みんな自分で見てもいいです.今期は些細なことを話しています.私たちのcrossbeamシリーズは今期で終わりましたか?そうですか.次回もあるかもしれませんが、お楽しみに~
crossbeam-util
AtomicCell
これは同時版の
std::cell::Cell
で、&self
に対して内部値を変更する効果を果たすことができて、主に以下の3つの方法を使います: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);
ShardedLock
これは
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);
}
WaitGroup
この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
のスレッド数は動的であることに注意してください.scope
これは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よりも便利になるのではないでしょうか~
crossbeam-queue
これは同時版のキューであり,実際には
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シリーズは今期で終わりましたか?そうですか.次回もあるかもしれませんが、お楽しみに~