用AI赚第一桶💰低成本搭建一套AI赚钱工具,源码可二开。 广告
[TOC] ## Boost.Asio是什么 Boost.Asio是一个跨平台的网络库 ## Boost.Asio怎么实现的 Linux下高性能网络库中大多使用的Reactor模式去实现,Boost.Asio在Linux下用epoll和select去模拟proactor模式,影响了它的效率和实现复杂度。为什么Boost.Asio使用Proactor模式呢?借用知乎上陈硕的回答来解释: >Windows 下很难实现高效可伸缩的 Reactor。首先,Win32 API 里 WaitForMultipleObjects 只能同时等待 64 个 handle (MAXIMUM\_WAIT\_OBJECTS);其次 WinSock 的 select() 实现又很 buggy,特别是在错误处理方面有很多奇葩行为(具体见各种跨平台网络库代码中对此的注释);最后,Windows Vista 新增的 WSAPoll() 函数与 POSIX 的 poll() 又不尽兼容( [http://daniel.haxx.se/blog/2012/10/10/wsapoll-is-broken/](https://link.zhihu.com/?target=http%3A//daniel.haxx.se/blog/2012/10/10/wsapoll-is-broken/) )。 >Windows 有自己的一套高效异步IO模型(几乎等同于Proactor),同时支持文件IO和网络IO;但 Linux 只有高效的网络同步IO(epoll 之类的 io multiplexing 是同步的Reactor,且不支持磁盘文件),二者的高效IO编程模型从根本上不兼容(Windows 可以把网络事件发到 GUI 线程的事件队列中,有点类似 Reactor,但是似乎一个进程只能有一个 GUI 线程,因此在多核系统上其伸缩性受限)。 因此,ASIO 要想高效且跨平台,只能用 Proactor 模型了。不可避免地会在 Linux 上损失一点儿效率。 ## 为什么 Proactor 是最佳模型? * 跨平台 许多操作系统都有异步API,即便是没有异步API的Linux, 通过 epoll 也能模拟 Proactor 模式。 * 支持回调函数组合 将一系列异步操作进行组合,封装成对外的一个异步调用。这个只有Proactor能做到,Reactor 做不到。意味着如果asio使用Reactor模式,就对不起他“库” 之名。 * 相比 Reactor 可以实现 Zero-copy * 和线程解耦。 长时间执行的过程总是由操作系统异步完成,应用程序无需为此开启线程。 Proactor 也并非全无缺点,缺点就是内存占用比 Reactor 大。**Proactor 需要先分配内存而后处理IO**, 而 **Reactor 是先等待 IO 而后分配内存**。相对的Proactor却获得了Zero-copy好处。因为内存已经分配好了,因此操作系统可以将接受到的网络数据直接从网络接口拷贝到应用程序内存,而无需经过内核中转。