mio这个库,我们基本可以从三个角度去切入:

  • 主要功能
  • 底层交互
  • 细节补充

主要功能

尝试使用把“大象装进冰箱”的理论来理解mio。

Mio的关键在于non-blocking I/O,也就是非阻塞IO。

什么是非阻塞IO(这里仅指同步非阻塞)?
大部分的博文都是这么解释的,当IO操作尚未就绪的时候,让出计算资源,其他任务被调度,等IO准备就绪时代码恢复执行。

这里有几个迷惑点:
1#“让出计算资源”,不就是阻塞了吗?
2#怎么才能知道IO准备好了?
3#计算资源让出后,其他任务是怎么被调度的?
4#这里到底有多少个任务?

带着这些疑问,先看一下mio的官方实例
如何构建一个非阻塞TCP服务端,三步走:

  1. 创建一个Poll实例、创建一个Events空间
  2. 注册事件源event source
  3. 创建事件循环event loop ```rust use mio::{Events, Poll, Interest, Token}; use mio::net::TcpStream;

use std::net::{self, SocketAddr};

// 创建Poll,创建event source let mut poll = Poll::new()?; let mut events = Events::with_capacity(1024);

// 注册事件 let addr: SocketAddr = “127.0.0.1:0”.parse()?; let server = net::TcpListener::bind(addr)?; let mut listener = TcpStream::accept(server.local_addr()?)?;

const SERVER = Token(0); poll.registry().register(&mut listener, SERVER, Interest::READABLE)?;

// 事件循环 loop { poll.poll(&mut events, Some(Duration::from_millis(100)))?;

  1. for event in events.iter() {
  2. match event.token() {
  3. SERVER => loop {
  4. match listener.accept() {
  5. Ok((connection, address)) => {
  6. println!("Got a connection from: {}", address);
  7. },
  8. Err(ref err) if would_block(err) => break,
  9. Err(err) => return Err(err),
  10. }
  11. }
  12. }
  13. }

}

fn would_block(err: &io::Error) -> bool { err.kind() == io::ErrorKind::WouldBlock } ``` “把大象装进冰箱”

  • 打开冰箱门
  • 把大象装进冰箱
  • 把冰箱门关上

感觉也不是很好解释这个事情,复杂了一些(但是没有完全复杂)。