3 个版本 (稳定)
1.1.0 | 2023 年 1 月 28 日 |
---|---|
1.0.0 | 2019 年 12 月 14 日 |
0.1.0 | 2019 年 10 月 23 日 |
#107 在 并发 中
156,387 每月下载量
用于 272 个 Crates (11 直接)
14KB
181 行
原子取
该库允许您存储一个值,您可以在以后原子地从其中取出。由于该库使用原子操作,取出值时无需锁定。
例如,您可以将 oneshot 通道的 Sender
存储在一个 AtomicTake
中,这将允许您在闭包第一次被调用时进行通知。
use atomic_take::AtomicTake;
use tokio::sync::oneshot;
let (send, mut recv) = oneshot::channel();
let take = AtomicTake::new(send);
let closure = move || {
if let Some(send) = take.take() {
// Notify the first time this closure is called.
send.send(()).unwrap();
}
};
closure();
assert_eq!(recv.try_recv().unwrap(), Some(()));
closure(); // This does nothing.
此外,上面的闭包可以从多个线程并发调用。例如,如果您将 AtomicTake
放入一个 Arc
中,您可以在多个线程之间共享它并接收第一个运行的线程的消息。
use std::thread;
use std::sync::Arc;
use atomic_take::AtomicTake;
use tokio::sync::oneshot;
let (send, mut recv) = oneshot::channel();
// Use an Arc to share the AtomicTake between several threads.
let take = Arc::new(AtomicTake::new(send));
// Spawn three threads and try to send a message from each.
let mut handles = Vec::new();
for i in 0..3 {
let take_clone = Arc::clone(&take);
let join_handle = thread::spawn(move || {
// Check if this thread is first and send a message if so.
if let Some(send) = take_clone.take() {
// Send the index of the thread.
send.send(i).unwrap();
}
});
handles.push(join_handle);
}
// Wait for all three threads to finish.
for handle in handles {
handle.join().unwrap();
}
// After all the threads finished, try to send again.
if let Some(send) = take.take() {
// This will definitely not happen.
send.send(100).unwrap();
}
// Confirm that one of the first three threads got to send the message first.
assert!(recv.try_recv().unwrap().unwrap() < 3);
该库不要求使用标准库。
支持的 Rust 版本
当前的 MSRV 是 1.48.0。它也可能在更早的编译器版本上运行,但在进行更改时并未在 CI 中进行测试。
许可证
本项目采用 MIT 许可证。
除非您明确声明,否则您有意提交以供本项目包含的任何贡献,均应按 MIT 许可证许可,不附加任何额外条款或条件。