当前位置:嗨网首页>书籍在线阅读

05-异步网络IO

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

12.3 异步网络I/O

正如我们在rudis_sync服务器实现中看到的那样,同步I/O模型可能是在给定时间内处理多个客户端的主要瓶颈,必须使用线程处理更多的客户端。但是,有一种更好的方法来扩展我们的服务器。我们可以让套接字是非阻塞的,而不是应对套接字的阻塞性质。对于非阻塞套接字,其上的任何读取、写入或连接操作都会立刻返回。也就是说,无论操作成功与否,如果读写的缓冲区部分被填充,它们不会阻塞调用代码。这就是异步I/O模型——没有客户端需要等待请求完成,而是稍后通知请求成功与否。

与线程相比,异步I/O模型非常高效,但它增加了代码的复杂性。在此模型中,因为套接字上的初次读取或写入调用不太可能成功,我们需要稍后再次尝试相同的操作。在套接字上重试的操作被称为轮询。我们需要不时地轮询套接字以查看是否可以完成相关的读取/写入/连接操作,并且还需要保持当前读取或写入的字节数的状态。当有大量传入套接字连接时,使用非阻塞套接字需要处理轮询和状态维护,这很快就会成为一个复杂的状态机。除此之外,轮询是一种非常低效的操作,即使我们的套接字上没有产生任何事件,不过我们有更好的解决方案。

在基于UNIX的平台上,套接字上的轮询机制是通过poll和select系统调用完成的,这些调用在所有UNIX操作系统上都是兼容的。除此之外,Linux还有一个更好的epoll API。它们可以告诉我们套接字何时可以读取或写入,而不是自己轮询套接字,因为这是一种低效的操作。在poll和select对每个请求的套接字运行for循环的情况下,epoll通过运行时间O(1)来通知用户新的套接字事件。

异步I/O模型允许用户处理比同步I/O模型规模更大的套接字,因为我们在小型数据块上执行操作,并能够快速切换以响应其他客户端的请求。另一个优点是我们不需要生产新的线程,因为这一切都发生在一个线程中。

为了使用非阻塞套接字编写异步网络应用程序,我们的Rust生态系统提供了一个高质量的软件包。