在* nix上了解异步编程的基础知识

时间:2012-01-08 08:57:46

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

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

以下是linux提供的几种替代方案:

  1. select / poll / epoll ::由于epoll仍在阻止调用,因此无法使用单线程完成。此外,必须以非阻塞模式打开受监视的文件描述符。
  2. libaio ::我所了解的是,它的实现很糟糕,而且仍然是基于通知而不是基于Windows I / O完成端口完成。
  3. 提升ASIO ::它在linux下使用epoll,因此不会产生真正的异步模式,因为它会生成完全从用户代码中抽象出来的线程来实现主动设计模式
  4. libevent ::如果我更喜欢ASIO,有什么理由可以选择吗?
  5. 现在问题出现了:)

    1. 使用epoll编写快速可扩展网络服务器的最佳设计模式是什么(当然,这里必须使用线程:()
    2. 我读过“只能在非阻塞模式下打开套接字”的地方,因此epoll仅支持套接字,因此不能用于磁盘I / O. 上述声明的真实性以及为什么无法使用epoll在磁盘I / O上进行异步编程?
    3. Boost ASIO围绕epoll电话使用一个大锁。我实际上并没有理解它的含义是什么以及如何使用asio本身克服它。 Similar question
    4. 如何修改ASIO模式以使用磁盘文件?有没有推荐的设计模式?
    5. 希望有人能够用很好的解释回答所有问题。任何链接到源,其中epoll和AIO设计模式的实现细节是开辟的也是赞赏。

2 个答案:

答案 0 :(得分:11)

  

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,它使用proactor设计模式。

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

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

  

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

如您所述,Asio库本身不支持文件I / O.有几次尝试将它添加到库中,我建议讨论mailing list

答案 1 :(得分:2)

首先:

  

得到证实,因为Linux(IOCP)仍然没有适用于Linux的TRULY异步模式(使用单线程并发)。

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

那么“反应堆”(epoll-like)API比“proactor”API(IOCP)更强大 第二个可以用第一个实现(但不是相反)。

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

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