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 异步

Download history 1756861/week @ 2024-05-04 1847762/week @ 2024-05-11 1842053/week @ 2024-05-18 1793663/week @ 2024-05-25 1986549/week @ 2024-06-01 1898347/week @ 2024-06-08 1884546/week @ 2024-06-15 1893543/week @ 2024-06-22 1750502/week @ 2024-06-29 1884958/week @ 2024-07-06 1894494/week @ 2024-07-13 2148114/week @ 2024-07-20 2238081/week @ 2024-07-27 2253956/week @ 2024-08-03 2580609/week @ 2024-08-10 2086562/week @ 2024-08-17

9,531,490 每月下载量
用于 23,738 个 crates(直接使用 440 个)

MIT 许可证

410KB
7K SLoC

Mio – 金属 I/O

Mio 是一个专注于非阻塞 API 和事件通知的快速、低级 I/O 库,旨在以尽可能少的开销构建高性能 I/O 应用程序,并基于操作系统抽象。

Crates.io MIT licensed Build Status Build Status

API 文档

这是一个低级库,如果您正在寻找更容易开始使用的库,请参阅 Tokio

使用方法

要使用 mio,首先将以下内容添加到您的 Cargo.toml

[dependencies]
mio = "1"

接下来,我们可以开始使用 Mio。以下是一个使用 TcpListenerTcpStream 的快速入门示例。请注意,此示例必须指定 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 系统访问套接字就绪事件。

不支持

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