3 个不稳定版本
0.2.1 | 2024 年 6 月 3 日 |
---|---|
0.2.0 | 2024 年 5 月 15 日 |
0.1.0 | 2023 年 7 月 16 日 |
在 异步 中排名 #65
每月下载量 23,201 次
在 22 个crate中使用(直接使用 9 个)
64KB
874 行
async-event
高效的异步条件变量,用于无锁算法,也称为 "eventcount"。
概述
Eventcount 类型的原语对于将某些操作应用于无锁结构非常有用,例如将有限队列转换为有限通道。这种原语允许感兴趣的任务在每次收到通知时检查谓词,直到谓词被满足为止而阻塞。
虽然功能上类似于 event_listener crate,但此实现更具有意见性,并且仅限于 async
情况。然而,它通过限制对互斥保护的通知列表的锁定操作的数量来提高效率:通常只锁定一次,每次等待者被阻塞和通知时,从而减少了同步操作的需求。最后,只有在不常见的情况下才会生成虚假唤醒。
请注意,如果您只需要向单个任务发送通知,则可以使用 Diatomic Waker crate 以获得更好的性能。
这个库是 Asynchronix 的一个分支,Asynchronix 是一个用于系统模拟的高性能异步计算框架的持续努力。它也用于 Tachyonix MPSC 通道。
使用方法
将以下内容添加到您的 Cargo.toml
[dependencies]
async-event = "0.2.1"
与 event_listener
的区别
此 Event
原语在一般情况下预计比 event_listener
crate 更快。然而,具体效果可能会根据您的特定应用程序而有所不同,因此您可能需要对两者进行基准测试。
API 更具有意见性,并且设计用于防止潜在的误用,例如
- 在请求通知后忘记再次检查谓词,即在对
Event::listen()
进行调用后,在event_listener
包中。async-event
提供了Event::wait_until
方法,该方法会在必要时检查谓词,以防止竞态条件。 - 在
event_listener
包中,notify
和notify_additional
之间的混淆。我们的经验和其他类似库的 API 表明,后者几乎总是用户所需要的,因此此包中notify*
方法的行为实际上类似于notify_additional
。 - 谓词的原子同步不足。
notify*
和wait_until
方法始终插入原子栅栏以确保适当的同步:没有与notify_additional_relaxed
相当的等效项。
示例
异步发送非零值
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::Arc;
use std::thread;
use futures_executor::block_on;
use async_event::Event;
let value = Arc::new(AtomicUsize::new(0));
let event = Arc::new(Event::new());
// Set a non-zero value concurrently.
thread::spawn({
let value = value.clone();
let event = event.clone();
move || {
// A relaxed store is sufficient here: `Event::notify*` methods insert
// atomic fences to warrant adequate synchronization.
value.store(42, Ordering::Relaxed);
event.notify_one();
}
});
// Wait until the value is set.
block_on(async move {
let v = event
.wait_until(|| {
// A relaxed load is sufficient here: `Event::wait_until` inserts
// atomic fences to warrant adequate synchronization.
let v = value.load(Ordering::Relaxed);
if v != 0 { Some(v) } else { None }
})
.await;
assert_eq!(v, 42);
});
非零值的单槽 MPMC 通道
请参阅 示例实现,位于 examples
目录中。
安全性
这是一个低级原语,因此其实现依赖于 unsafe
。测试套件广泛使用了 Loom 和 MIRI 来评估其正确性。然而,尽管它们很神奇,但 Loom 和 MIRI 不能正式证明数据竞争的不存在,因此可能会出现可靠性问题。
许可证
此软件根据您的选择,许可在 Apache License, Version 2.0 或 MIT 许可证 下。
贡献
除非您明确声明,否则根据 Apache-2.0 许可证定义,您提交的任何有意提交以包含在作品中的贡献,都将按上述方式双许可,而不附加任何额外条款或条件。
依赖项
~0–27MB
~330K SLoC