C++ 如果Proactor设计模式更适合异步I/O,为什么不';它在亚洲不违约吗?

C++ 如果Proactor设计模式更适合异步I/O,为什么不';它在亚洲不违约吗?,c++,c++14,boost-asio,C++,C++14,Boost Asio,我最近在一次代码审查中被狠狠地揍了一顿,在接口适配器中实现了一个ASIO UDP套接字;似乎实现了另一个输入UDP套接字,并且假设输入和输出都在同一个线程上。所以,我想知道为什么ASIO套接字库不维护一个静态线程(套接字上下文)并对每个套接字使用它?采用PROFER模式的动机和权衡是什么? 编辑/补遗 在看到一些关于我的问题的评论不清楚之后,我将根据类定义添加此代码段,该类定义告诉我没有遵循Proactor模式: class InterfaceAdapter{ public: typ

我最近在一次代码审查中被狠狠地揍了一顿,在接口适配器中实现了一个ASIO UDP套接字;似乎实现了另一个输入UDP套接字,并且假设输入和输出都在同一个线程上。所以,我想知道为什么ASIO套接字库不维护一个静态线程(套接字上下文)并对每个套接字使用它?采用PROFER模式的动机和权衡是什么?

编辑/补遗

在看到一些关于我的问题的评论不清楚之后,我将根据类定义添加此代码段,该类定义告诉我没有遵循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);
};
类接口适配器{
公众:
typedef std::向量MsgPackets;
InterfaceAdapter():
mySocket(myContext){}
无效发送数据到系统(常量数据结构和原始数据);
私人:
asio::io_context myContext;
asio::ip::udp::socket mySocket;
MsgPackets transformData(常量数据结构和原始数据);
无效发送包(常量MsgPackets和msg);
};

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

您的问题不是很清楚,也不是很复杂,我想这也是您的问题的原因:

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

Boost ASIO为您提供了这种自由,这个库在没有任何动机的情况下将自己限制在这个角落是没有意义的。静态或全局变量(即线程)也被广泛认为是极端糟糕的样式

然而,您的问题表明,您的程序(即体系结构)设计为单线程,并且您编写的代码使用ASIO,就像使用多线程一样(无论如何,在运行时不会有任何显著的开销),或者您的审阅者也误解了boost ASIO语义。如果没有您的代码和具体的原因,这仍然很困难

您的附录的附录: 不,我不必是全局的,我假设审阅者的观点是您有自己的
asio::io_context
,这通常是不需要的,因为您的类似乎只是发送数据包,所以对于它来说,它应该与它在哪个
io_context
上运行无关。这就是为什么boost sockets和类似的东西只是引用一个
io\U上下文
,这是我自己做的,例如。在这里,您可以看到我只存储了对整个RTSP视频流服务器管理的
io\U上下文的引用

但是,我担心您的公司/审阅者不会使用boost asio,否则您的适配器可能是第一个使用boost asio internal的适配器,但无意泄露此实现细节。然后这取决于类的使用方式:在整个程序生命周期中通常只有一个实例吗?然后它可以管理自己的
io\u上下文
,但我假设您更愿意创建它的几个实例。想象一下boost tcp连接,即为服务器本身创建线程和所有内容的套接字,对于服务器拥有的每个tcp连接,这将是愚蠢的

因此,解决方案可能是在构造函数中使用
io\u上下文&
,或者如果想要避免boost细节,则另一个由您设计的类,
interfacedapter
的创建者必须保留该类,并在每次创建新接口适配器时重复使用。然而,如果这不可能,那么你就应该真正重构你的整个程序,但那将是平庸者开始使用globals的时候。但是,不要让你的
interfacedapter
boost::io_context
全局化,而是像
class my_io_singleton
这样的东西,它仍然必须放在你的interfacedapter中,这样,在更好的一天,你的代码将很容易被重构

更新2
下一件事可能会让你再次失控,因此我建议你在阅读上述部分之后,以及在你使用boost asio进行了更多的实现之后,再阅读它,因为它对你的案例来说并不重要也不相关:公平地说,boost
io\U上下文
看起来像是单例的情况很少发生,但这只是asio内置的舒适功能,有人可能会认为,最好将其忽略。但它们可以被忽略

你的问题不是很清楚,也不是很复杂,我想这也是你问题的原因:

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

Boost ASIO为您提供了这种自由,这个库在没有任何动机的情况下将自己限制在这个角落是没有意义的。静态或全局变量(即线程)也被广泛认为是极端糟糕的样式

然而,您的问题表明,您的程序(即体系结构)设计为单线程,并且您编写的代码使用ASIO,就像使用多线程一样(无论如何,在运行时不会有任何显著的开销),或者您的审阅者也误解了boost ASIO语义。如果没有您的代码和具体的原因,这仍然很困难

您的附录的附录: 不,我不必是全局性的,我假设审阅者的观点是,您有自己的
asio::io_上下文
,这通常是不需要的,因为