64 个版本 (3 个稳定版)
1.0.2 | 2024 年 8 月 12 日 |
---|---|
1.0.1 | 2024 年 7 月 23 日 |
1.0.0 | 2024 年 6 月 14 日 |
0.8.11 | 2024 年 3 月 1 日 |
0.1.0 | 2014 年 11 月 11 日 |
#1 in 异步
9,531,490 每月下载量
用于 23,738 个 crates(直接使用 440 个)
410KB
7K SLoC
Mio – 金属 I/O
Mio 是一个专注于非阻塞 API 和事件通知的快速、低级 I/O 库,旨在以尽可能少的开销构建高性能 I/O 应用程序,并基于操作系统抽象。
API 文档
这是一个低级库,如果您正在寻找更容易开始使用的库,请参阅 Tokio。
使用方法
要使用 mio
,首先将以下内容添加到您的 Cargo.toml
[dependencies]
mio = "1"
接下来,我们可以开始使用 Mio。以下是一个使用 TcpListener
和 TcpStream
的快速入门示例。请注意,此示例必须指定 features = ["os-poll", "net"]
。
use std::error::Error;
use mio::net::{TcpListener, TcpStream};
use mio::{Events, Interest, Poll, Token};
// Some tokens to allow us to identify which event is for which socket.
const SERVER: Token = Token(0);
const CLIENT: Token = Token(1);
fn main() -> Result<(), Box<dyn Error>> {
// Create a poll instance.
let mut poll = Poll::new()?;
// Create storage for events.
let mut events = Events::with_capacity(128);
// Setup the server socket.
let addr = "127.0.0.1:13265".parse()?;
let mut server = TcpListener::bind(addr)?;
// Start listening for incoming connections.
poll.registry()
.register(&mut server, SERVER, Interest::READABLE)?;
// Setup the client socket.
let mut client = TcpStream::connect(addr)?;
// Register the socket.
poll.registry()
.register(&mut client, CLIENT, Interest::READABLE | Interest::WRITABLE)?;
// Start an event loop.
loop {
// Poll Mio for events, blocking until we get an event.
poll.poll(&mut events, None)?;
// Process each event.
for event in events.iter() {
// We can use the token we previously provided to `register` to
// determine for which socket the event is.
match event.token() {
SERVER => {
// If this is an event for the server, it means a connection
// is ready to be accepted.
//
// Accept the connection and drop it immediately. This will
// close the socket and notify the client of the EOF.
let connection = server.accept();
drop(connection);
}
CLIENT => {
if event.is_writable() {
// We can (likely) write to the socket without blocking.
}
if event.is_readable() {
// We can (likely) read from the socket without blocking.
}
// Since the server just shuts down the connection, let's
// just exit from our event loop.
return Ok(());
}
// We don't expect any events with tokens other than those we provided.
_ => unreachable!(),
}
}
}
}
功能
- 非阻塞 TCP、UDP、UDS
- 由 epoll、kqueue 和 IOCP 支持的 I/O 事件队列
- 运行时无分配
- 平台特定扩展
非目标
以下内容从 Mio 中特别省略,留给用户或高级库。
- 文件操作
- 线程池/多线程事件循环
- 计时器
平台
当前支持的平台
- Android(API 级别 21)
- DragonFly BSD
- FreeBSD
- Linux
- NetBSD
- OpenBSD
- Windows
- iOS
- macOS
Mio 可以处理与上述平台的每个事件系统的接口。它们的实现细节在 API 文档中的 Poll
类型中进一步讨论(见上文)。
Mio 通常支持上述提到的平台的与 Rust 语言(rustc)相同的版本,除非另有说明。
Windows 实现轮询套接字使用的是 wepoll 策略。这使用 Windows AFD 系统访问套接字就绪事件。
不支持
- Wine,请参阅 问题 #1444
MSRV 政策
MSRV(最低支持 Rust 版本)对于给定的次要版本(1.x)是固定的。然而,在升级次要版本时,例如从 1.0 升级到 1.1,我们可以提高 MSRV。无法提高 Rust 版本的用户可以使用较旧的次要版本。以下是 Mio 版本及其 MSRV 的列表
- v0.8: Rust 1.46。
- v1.0: Rust 1.70。
但是请注意,Mio 还有一些依赖项,这些依赖项可能具有不同的 MSRV 政策。我们在更新依赖项时尽量遵守上述策略,但这并不总是可能的。
不支持标志
Mio 根据平台使用不同的实现来支持相同的功能。Mio 通常使用对 Mio 的用例来说“最佳”的实现,其中“最佳”通常意味着对 Mio 的用例来说效率最高。然而,这意味着实现通常针对有限的平台数量,这意味着我们通常有多个实现来支持相同的功能。在某些情况下,可能需要不使用“最佳”实现,而是使用 Mio 支持的其他实现(在其他平台上)。Mio 不正式支持平台上的二级实现,但我们确实有各种 cfg 标志来强制在这些情况下使用另一个实现。
当前标志
mio_unsupported_force_poll_poll
,使用基于poll(2)
的实现来为mio::Poll
。mio_unsupported_force_waker_pipe
,使用基于pipe(2)
的实现来为mio::Waker
。
再次强调,Mio 不正式支持这。此外,这些标志可能会在未来消失。
社区
一组 Mio 用户在 Discord 上闲逛,这可能是一个提问的好地方。您也可以在 GitHub 上 新建一个问题 来提问、报告错误或建议新功能。
贡献
有兴趣参与其中吗?我们非常乐意帮助您!对于简单的错误修复,只需提交包含修复的 PR,我们可以在 PR 中直接讨论修复方案。如果修复更为复杂,请从问题开始。
如果您想提出 API 变更,创建一个问题以与社区开始讨论。您也可以在 Discord 中与我们交谈。
最后,请保持友好。我们支持 Rust 行为准则。
依赖项
~0–8.5MB
~63K SLoC