一段时间以来,我一直在谷歌上搜索很多东西,以了解在 nix 机器上实现异步编程/行为的各种方法,并且(如我之前所知)确认仍然没有真正的异步这一事实模式(使用单线程的并发)适用于 Windows (IOCP)。
以下是 linux 的几个替代方案:
- select/poll/epoll::无法使用单线程完成,因为 epoll 仍在阻塞调用。此外,受监控的文件描述符必须以非阻塞模式打开。
- libaio::我了解到的是它的实现很糟糕,而且它仍然基于通知,而不是像 Windows I/O 完成端口那样基于完成。
- Boost ASIO::它在 linux 下使用 epoll,因此不是真正的异步模式,因为它产生了完全从用户代码中抽象出来的线程以实现前摄器设计模式
- libevent::如果我更喜欢 ASIO,有什么理由选择它?
现在问题来了:)
- 使用 epoll 编写快速可扩展的网络服务器的最佳设计模式是什么(当然,这里必须使用线程:()
- 我在某处读到“只能在非阻塞模式下打开套接字”,因此 epoll 仅支持套接字,因此不能用于磁盘 I/O。 上面的说法有多真实,为什么不能使用 epoll 在磁盘 I/O 上进行异步编程?
- Boost ASIO 在 epoll 调用周围使用了一个大锁。我实际上并不了解它的含义以及如何使用 asio 本身来克服它。 Similar question
- 如何修改 ASIO 模式以处理磁盘文件?有没有推荐的设计模式?
希望有人能够用很好的解释来回答所有问题。任何解释 epoll 和 AIO 设计模式的实现细节的源链接也很感激。
最佳答案
Boost ASIO :: It uses epoll under linux and thus not a true async pattern as it spawns thread which are completely abstracted from user code to acheive the proactor design pattern
这是不正确的。 Asio 库在最新的 Linux 内核版本上默认使用 epoll()
。但是,调用 io_service::run()
的线程将根据需要调用回调处理程序。 Asio 库中只有一个地方使用线程来模拟异步接口(interface),在 documentation 中有很好的描述。 :
An additional thread per io_service is used to emulate asynchronous host resolution. This thread is created on the first call to either
ip::tcp::resolver::async_resolve()
orip::udp::resolver::async_resolve()
.
这并不像您声称的那样使库“不是真正的异步模式”,实际上它的名称与您的定义不同。
1) What would be the best design pattern for writing fast scalable network server using epoll (of course, will have to use threads here :( )
我建议使用 Boost Asio,它使用前摄器设计模式。
3) Boost ASIO uses one big lock around epoll call. I didnt actually understand what can be its implications and how to overcome it using asio itself
epoll react 器使用互斥体来调度处理程序,尽管实际上这对大多数应用程序来说并不是一个大问题。有一些特定于应用程序的方法可以缓解这种行为,例如每个 CPU 的 io_service
以利用数据局部性。见 my answer关于这个主题的类似问题。 Asio mailing list 上也有讨论。经常。
4) How can I modify ASIO pattern to work with disk files? Is there any recommended design pattern?
如您所述,Asio 库本身并不支持文件 I/O。已经多次尝试将其添加到库中,我建议在 mailing list 上讨论.
关于c++ - 在 *nix 上了解异步编程的基础知识,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8776416/