mio这个库,我们基本可以从三个角度去切入:
- 主要功能
- 底层交互
- 细节补充
主要功能
尝试使用把“大象装进冰箱”的理论来理解mio。
Mio的关键在于non-blocking I/O,也就是非阻塞IO。
什么是非阻塞IO(这里仅指同步非阻塞)?
大部分的博文都是这么解释的,当IO操作尚未就绪的时候,让出计算资源,其他任务被调度,等IO准备就绪时代码恢复执行。
这里有几个迷惑点:
1#“让出计算资源”,不就是阻塞了吗?
2#怎么才能知道IO准备好了?
3#计算资源让出后,其他任务是怎么被调度的?
4#这里到底有多少个任务?
带着这些疑问,先看一下mio的官方实例。
如何构建一个非阻塞TCP服务端,三步走:
- 创建一个
Poll实例、创建一个Events空间 - 注册事件源
event source - 创建事件循环
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)))?;
for event in events.iter() {match event.token() {SERVER => loop {match listener.accept() {Ok((connection, address)) => {println!("Got a connection from: {}", address);},Err(ref err) if would_block(err) => break,Err(err) => return Err(err),}}}}
}
fn would_block(err: &io::Error) -> bool { err.kind() == io::ErrorKind::WouldBlock } ``` “把大象装进冰箱”
- 打开冰箱门
- 把大象装进冰箱
- 把冰箱门关上
感觉也不是很好解释这个事情,复杂了一些(但是没有完全复杂)。
