1 个不稳定版本
0.1.0 | 2023年9月26日 |
---|
#1353 in 异步
240KB
4.5K SLoC
CompleteIo
基于 IOCP/io_uring/mio 的每个核心的 Rust IO 驱动程序和异步运行时。名称来源于“基于完成的 IO”。
此存储库是 compio 的分支。
为什么不使用 Compio?
项目有不同的目标
-
提供低开销的 IO 驱动程序,在初始化时预分配内存
-
驱动程序 API 接受非 'static IO 缓冲区
- 驱动程序不拥有缓冲区
- 缓冲区必须为 Unpin
-
偏向于 IoUring API 以在 Linux 上实现零成本抽象
- 操作固定大小提交队列
- 外部运行时可以将尚未排队操作的队列作为单个批次提交
- 计时器作为
Timeout
操作公开,并使用当可用时具有挂起感知的 CLOCK_BOOTTIME 时钟源
-
异步运行时是测试驱动程序实现的示例运行时
快速入门
启用 runtime
功能后,我们可以使用高级 API 执行 fs & net IO。
use completeio::{fs::File, task::block_on};
let buffer = block_on(async {
let file = File::open("Cargo.toml").unwrap();
let (read, buffer) = file.read_to_end_at(Vec::with_capacity(1024), 0).await;
let read = read.unwrap();
assert_eq!(read, buffer.len());
String::from_utf8(buffer).unwrap()
});
println!("{}", buffer);
同时,您也可以手动控制低级驱动程序
use arrayvec::ArrayVec;
use std::collections::VecDeque;
use completeio::{
buf::IntoInner,
driver::{AsRawFd, Driver, Entry, CompleteIo},
fs::File,
op::ReadAt,
};
let mut driver = Driver::new().unwrap();
let file = File::open("Cargo.toml").unwrap();
// Attach the `RawFd` to driver first.
driver.attach(file.as_raw_fd()).unwrap();
// Create operation and push it to the driver.
let mut op = ReadAt::new(file.as_raw_fd(), 0, Vec::with_capacity(4096));
let mut ops = VecDeque::from([(&mut op, 0).into()]);
driver.push_queue(&mut ops);
// Poll the driver and wait for IO completed.
let mut entries = ArrayVec::<Entry, 1>::new();
unsafe {
driver
.submit_and_wait_completed(None, &mut entries)
.unwrap();
}
let entry = entries.drain(..).next().unwrap();
assert_eq!(entry.user_data(), 0);
// Resize the buffer by return value.
let n = entry.into_result().unwrap();
let mut buffer = op.into_inner();
unsafe {
buffer.set_len(n);
}
println!("{}", String::from_utf8(buffer).unwrap());
依赖项
~0.2–13MB
~102K SLoC