【发布时间】:2014-07-16 05:26:33
【问题描述】:
我正在考虑在我们目前使用的现有专有第 3 方网络协议之上编写自定义 Asio 服务。
根据Highscore Asio guide需要实现三个类来创建自定义的Asio服务:
- 派生自
boost::asio::basic_io_object的类,表示新的 I/O 对象。 - 派生自
boost::asio::io_service::service的类,表示向 I/O 服务注册并可从 I/O 对象访问的服务。 - 不是从代表服务实现的任何其他类派生的类。
网络协议实现已经提供了异步操作并且有一个(阻塞的)事件循环。所以我想,我会把它放到我的服务实现类中,并在内部工作线程中运行事件循环。到目前为止一切顺利。
查看自定义服务的一些示例,我注意到服务类产生了它们自己的内部线程(实际上它们实例化了它们自己的内部 io_service 实例)。例如:
高分页面提供directory monitor example。它本质上是一个围绕 inotify 的包装器。有趣的类是
inotify/basic_dir_monitor_service.hpp和inotify/dir_monitor_impl.hpp。Dir_monitor_impl处理与 inofity 的实际交互,这是阻塞的,因此在后台线程中运行。我同意这一点。但是basic_dir_monitor_service也有一个内部工作线程,似乎正在做的只是在主的io_service和dir_monitor_impl之间混洗请求。我修改了代码,删除了basic_dir_monitor_service中的工作线程,而是直接将请求发布到主 io_service 并且程序仍然像以前一样运行。在 Asio 的 custom logger service example 中,我注意到了相同的方法。
logger_service产生一个内部工作线程来处理日志记录请求。我没有时间玩那些代码,但我认为应该可以将这些请求直接发布到主 io_service。
拥有这些“中介工人”有什么好处?您不能一直将所有工作都发布到主 io_service 吗?我是否遗漏了 Proactor 模式的一些关键方面?
我可能应该提到我正在为一个功率不足的单核嵌入式系统编写软件。拥有这些额外的线程似乎只是强加了不必要的上下文切换,我希望尽可能避免。
【问题讨论】:
-
很棒的问题。这些天我打算尝试那个特定的例子。很高兴看到其他人与之对战。稍后阅读
-
@sehe 来自你的哇,这意味着什么。我在 SO 上多次注意到你的句柄。通常会回答一些令人费解的 Boost.Spirit 问题
-
关于 inotify 的一个注意事项:它不必阻塞。事实上,它经常与 epoll 或 select 或类似的一起使用。
-
@John 是的,这是真的! inotify 页面说这是可能的,但建议不要这样做……但他们知道什么:) 所以,理论上应该也可以放弃该线程?
-
它在哪里建议不要使用非阻塞?我在我检查的参考文献中没有看到类似的东西。
标签: c++ boost boost-asio