#atomic #lock-free #options #take

不依赖 std atomic-take

从容器中原子地取一次值

3 个版本 (稳定)

1.1.0 2023 年 1 月 28 日
1.0.0 2019 年 12 月 14 日
0.1.0 2019 年 10 月 23 日

#107并发

Download history 74284/week @ 2024-03-14 79044/week @ 2024-03-21 78437/week @ 2024-03-28 83414/week @ 2024-04-04 81369/week @ 2024-04-11 75391/week @ 2024-04-18 43985/week @ 2024-04-25 40157/week @ 2024-05-02 39949/week @ 2024-05-09 38142/week @ 2024-05-16 49149/week @ 2024-05-23 47217/week @ 2024-05-30 37551/week @ 2024-06-06 38491/week @ 2024-06-13 42419/week @ 2024-06-20 30203/week @ 2024-06-27

156,387 每月下载量
用于 272 个 Crates (11 直接)

MIT 许可证

14KB
181

原子取

License Cargo Documentation

该库允许您存储一个值,您可以在以后原子地从其中取出。由于该库使用原子操作,取出值时无需锁定。

例如,您可以将 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 许可证许可,不附加任何额外条款或条件。

无运行时依赖