16

一段时间以来,我一直在谷歌上搜索很多方法来了解在 nix 机器上实现异步编程/行为的各种方法,并且(如我之前所知)确认仍然没有真正的异步模式(并发使用单线程)适用于 Linux,适用于 Windows(IOCP)。

以下是 linux 的一些替代方案:

  1. select/poll/epoll :: 不能使用单线程完成,因为 epoll 仍然阻塞调用。此外,受监视的文件描述符必须以非阻塞模式打开。
  2. libaio :: 我所知道的是它的实现很糟糕,它仍然基于通知,而不是像 Windows I/O 完成端口那样基于完成。
  3. Boost ASIO ::它在linux下使用epoll,因此不是真正的异步模式,因为它产生了完全从用户代码中抽象出来的线程以实现前摄器设计模式
  4. libevent :: 如果我更喜欢 ASIO,有什么理由这样做吗?

现在问题来了:)

  1. 使用 epoll 编写快速可扩展网络服务器的最佳设计模式是什么(当然,这里必须使用线程:()
  2. 我在某处读到“只能在非阻塞模式下打开套接字”,因此 epoll 仅支持套接字,因此不能用于磁盘 I/O。上面的陈述有多真实,为什么不能使用 epoll 在磁盘 I/O 上进行异步编程?
  3. Boost ASIO 在 epoll 调用周围使用了一个大锁。我实际上并不了解它的含义以及如何使用 asio 本身来克服它。类似的问题
  4. 如何修改 ASIO 模式以使用磁盘文件?有没有推荐的设计模式?

希望有人也能用很好的解释来回答所有问题。任何指向说明 epoll 和 AIO 设计模式的实现细节的源链接也值得赞赏。

4

2 回答 2

12

Boost ASIO ::它在linux下使用epoll,因此不是真正的异步模式,因为它产生了完全从用户代码中抽象出来的线程以实现前摄器设计模式

这是不正确的。Asio 库epoll()默认用于最新的 Linux 内核版本。但是,调用的线程io_service::run()将根据需要调用回调处理程序。Asio 库中只有一个地方使用线程来模拟异步接口,文档中对此进行了很好的描述

每个 io_service 的附加线程用于模拟异步主机解析。该线程是在第一次调用 ip::tcp::resolver::async_resolve()或 时创建的ip::udp::resolver::async_resolve()

这并不像您声称的那样使库“不是真正的异步模式”,实际上它的名称根据定义与您不同。

1)使用epoll编写快速可扩展网络服务器的最佳设计模式是什么(当然,这里必须使用线程:()

我建议使用 Boost Asio,它使用前摄器设计模式。

3) Boost ASIO 在 epoll 调用周围使用了一个大锁。我实际上并没有理解它的含义以及如何使用 asio 本身来克服它

epoll 反应器使用互斥体来调度处理程序,尽管实际上这对大多数应用程序来说并不是一个大问题。有一些特定于应用程序的方法可以缓解这种行为,例如io_service每个 CPU 来利用数据局部性。请参阅对有关此主题的类似问题的回答。Asio 邮件列表上也经常讨论它。

4) 如何修改 ASIO 模式以使用磁盘文件?有没有推荐的设计模式?

如您所述,Asio 库本身不支持文件 I/O。已经多次尝试将其添加到库中,我建议在邮件列表中讨论。

于 2012-01-08T13:06:05.560 回答
2

首先:

得到证实,Linux 仍然没有真正的异步模式(使用单线程并发)可用于 Windows(IOCP)。

你可能有一个小小的误解,异步可以建立在“轮询”api之上。

不仅如此,“reactor”(类似 epoll)API 比“proactor”API (IOCP) 更强大,因为第二个 API 可以根据第一个实现(但不能反过来)。

还有一些“真正”异步的操作,例如磁盘 I/O,其他一些工具可以结合信号,Linux 特定signalfd可以提供对其他一些情况的全面覆盖。

底线。epoll真正的异步 I/O

于 2012-01-08T13:26:34.013 回答