【问题标题】:Getting to know the basics of Asynchronous programming on *nix在 *nix 上了解异步编程的基础知识
【发布时间】:2012-02-05 06:42:09
【问题描述】:

一段时间以来,我一直在谷歌上搜索很多东西,以了解在 nix 机器上实现异步编程/行为的各种方法,并且(如我之前所知)确认仍然没有真正的异步这一事实模式(使用单线程的并发)适用于 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 本身来克服它。 Similar question
  4. 如何修改 ASIO 模式以处理磁盘文件?有没有推荐的设计模式?

希望有人能够用很好的解释来回答所有问题。任何解释 epoll 和 AIO 设计模式的实现细节的源链接也很感激。

【问题讨论】:

  • 所有selectpollepoll都有一个可以为零的超时参数,这使得函数立即返回。
  • 另外,有通知,就像aio_*函数的情况一样异步的。您要求在事件发生时得到通知,然后在内核处理您的 I/O 时继续您的业务。
  • epoll_wait 不一定是阻塞调用;这取决于传递给它的超时参数(“man epoll_wait”了解详细信息)。
  • 有什么理由避免线程?你知道性能问题吗?
  • @Joachim:是的,我知道这个事实。这是否意味着我可以使用 epoll 零超时的单线程实现真正的异步设计模式?

标签: c++ c boost-asio epoll aio


【解决方案1】:

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

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

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

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

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

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

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

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

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

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

【讨论】:

  • 山姆,感谢您的超级回答。您能否对第 2 个问题也有所了解?我没有清楚地了解epoll部分的asio lock,但我会尝试更深入地研究它并得到答案。
【解决方案2】:

首先:

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

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

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

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

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

【讨论】:

  • 感谢您的回答,但您能否查看 Joachim 对我的问题的最后评论.. 他的观点并非如此
  • 我认为他的意思是从套接字读取时的 memcopy 不是异步的,因此 epoll 不是完全异步的。 iocp 允许您在触发异步时指定数据所在的缓冲区。操作,你不能用 epoll 来做。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-11
  • 2021-04-07
  • 2011-06-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多