如果Proactor设计模式优于异步I / O,为什么它不是默认的ASIO?

问题描述 投票:0回答:1

我最近在代码审查中非常努力,在接口适配器中实现了ASIO UDP套接字;似乎已经实现了另一个输入UDP套接字,并且假设输入和输出都在同一个线程上。所以,我想知道为什么ASIO套接字库不维护静态线程(套接字上下文)并为每个套接字使用它?使用Proactor模式时需要考虑的动机和权衡取舍是什么?

编辑/附录

在看到关于我的问题的一些评论不清楚之后,我正在根据我被告知没有遵循Proactor模式的类定义添加此代码片段:

class InterfaceAdapter{
  public:
    typedef std::vector<MsgFragment> MsgPackets;
    InterfaceAdapter() :
      mySocket(myContext) {}
    void sendDataToSystem(const DataStruct& originalData);
  private:
    asio::io_context myContext;
    asio::ip::udp::socket mySocket;
    MsgPackets transformData(const DataStruct& originalData);
    void sendPackets(const MsgPackets& msgs);
};

显然我需要使用全局范围的asio::io_context而不是将它作为私有成员并使用它来默认构造套接字?

c++ c++14 boost-asio
1个回答
2
投票

你的问题不是很清楚,混合或暗示事物,我认为这也是你问题的原因:

Boost ASIO是一个proactor模式,异步处理程序通常在另一个处理程序完成后执行,即回调。如果用户通过在多于1个线程上运行boost::asio::io_context::run来选择,则可以同时执行此操作。

Boost ASIO为您提供了自由,没有任何动力,这个图书馆将自己局限于这个角落是没有意义的。静态或全局变量,即线程也被广泛地视为极端坏的风格。

但是你的问题表明你的程序即架构设计为单线程,你编写的代码使用ASIO就像使用多个线程一样(在运行时不应该有任何重大开销),或者你的审阅者也误解了提升ASIO语义。没有你的代码和具体原因,这仍然是很难的猜测。

你的附录的附录:不,我不必是全球性的,我认为评论者指出你有自己的asio::io_context,你通常不需要,因为你的课程似乎只是发送数据包,所以对于它,应该对它运行的io_context无动于衷。多数民众赞成插座和类似的原因只是参考io_context,我这样做我自己,例如RTP class I wrote。在那里你可以看到我只存储了对整个RTSP Videostreaming服务器管理的io_context的引用。

但是我担心你的公司/审阅者不会使用boost asio,你的适配器可能是第一个使用boost asio internal但不打算泄露这个实现细节的人。然后它取决于你的类的使用方式:整个程序生命周期中通常只有一个实例,like this?然后它可以管理它自己的io_context,但我认为你宁愿创建它的几个实例。想象一下boost tcp连接,即套接字创建线程和一切只为自己,对于服务器的每个tcp连接,这将是愚蠢的。

那么解决方案就是要么只是在你的构造函数中使用io_context&,或者如果那时想要避免增强细节,另一个由你设计的类,InterfaceAdapter的创建者必须保留,并在每次创建新接口时重用适配器。但是,如果这不可能,那么你应该真正重构整个程序,但这将是平庸开始使用全局变量的时刻。但是,不要让你的InterfaceAdapterboost::io_context全局,但像class my_io_singleton这样的东西仍然必须提供给你的InterfaceAdpater,以便更好的一天,你的代码将很容易重构。

更新2接下来的事情可能会让你再次陷入困境,所以我建议你只有在阅读完上面的内容之后才能阅读它,并且在你使用boost asio做了更多的实现之后,因为它对你的情况来说并不重要也不相关:公平有一个极少数情况下,加速io_contexts似乎是单身,像I stumbled over myself,但这只是asio建立的舒适功能,人们可能会争辩可能更好地被遗漏。但他们可以简单地被忽视。

© www.soinside.com 2019 - 2024. All rights reserved.