C++ 在一个线程中异步读取多个使用者的一个套接字
我正在实现一个连接多路复用器类,它封装单个连接,以便提供在其上创建所谓的C++ 在一个线程中异步读取多个使用者的一个套接字,c++,asynchronous,networking,boost-asio,fibers,C++,Asynchronous,Networking,Boost Asio,Fibers,我正在实现一个连接多路复用器类,它封装单个连接,以便提供在其上创建所谓的流的能力。在一个物理连接上可以有几十个这样的流 通过该连接发送的消息由协议定义,可以是客户端从未看到的服务消息(拥塞控制等),也可以是数据消息-它们包含流的一些数据,其中一个在相应消息的头中定义 我在为流实现方法read时遇到了一个问题。它必须是阻塞的,但是是异步的,因此它返回一些值-数据读取或发生错误-但是请求本身必须是某种异步队列 为了实现异步网络IO,我们使用了Boost的async\u read-s、async\u
流的能力。在一个物理连接上可以有几十个这样的流
通过该连接发送的消息由协议定义,可以是客户端从未看到的服务消息(拥塞控制等),也可以是数据消息-它们包含流的一些数据,其中一个在相应消息的头中定义
我在为流
实现方法read
时遇到了一个问题。它必须是阻塞的,但是是异步的,因此它返回一些值-数据读取或发生错误-但是请求本身必须是某种异步队列
为了实现异步网络IO,我们使用了Boost的async\u read
-s、async\u write
-s等,以及从另一个库中获取的完成令牌。因此,对MyConnection::undernative\u connection::read(size\u t)
的调用在我前面描述的术语中已经是异步的
我实现的一个解决方案是函数MyConnection::processFrame()
,它从连接中读取、处理消息,如果是数据消息,则将数据放入相应流的缓冲区。该函数将在流的read
的循环中调用。但是,在这种情况下,可以有多个同时调用async\u read
,即UB。此外,这意味着即使是服务消息也要等待,直到某个流想要读取数据,这也是不合适的
我提出的另一个解决方案是使用future
-s,但正如我所检查的,他们的方法wait/get
会阻塞整个线程(即使是延迟策略或成对承诺),这也必须避免
下面是一个简单的示例,其中只包含理解问题所需的方法。这是当前的实现,其中包含bug
struct低层连接{
///第三部分库的完成令牌-ufibers
产量&产量;
///asio插座
TcpSocket插座;
///完全异步(在一个线程中)方法
std::矢量读取(大小\u t字节){
std::向量res;
res.reserve(字节);
boost::asio::异步读取(socket、res、yield);
返回res;
}
}
结构MyConnection{
///页眉总是那个长度
constexpr uint32_t kHeaderSize=12;
///潜在联系
低电平连接;
///在连接启动的所有时间都在运行
void readLoop(){
while(connection.isActive()){
自动消息=连接读取(kHeaderSize);
if(msg.type==SERVICE){handleService(msg);return;}
//这是数据信息,请阅读其中的另一部分
自动数据=连接读取(消息数据大小);
//将数据放入流的缓冲区
streams.find(data.stream.id).buffer.put(data);
}
}
}
结构流{
缓冲区;
//还有异步阻塞方法
std::矢量读取(uint32_t字节){
//在完美的场景中,应该是这样的
async_wait([](){return buffer.size()>=bytes;});
//返回“bytes”大小的子缓冲区并将其删除
返回subbufer。。。
}
}
谢谢你以后的回答 请详细说明您提供的接口的要求,“阻塞,但异步”不清楚。使用流的代码是否使用回调/协同路由/光纤/?另外,在您的场景中,谁来管理执行器/光纤?“阻塞,但异步”没有多大意义,在术语上像ConyRadion一样查找。@Zulan。通过“阻塞,但异步”我的意思是,你调用这个方法,它直接返回一些值,没有回调,等等,但在后台,它使用光纤来管理多任务-因此没有创建线程,但一个线程仍然没有被阻塞,即使没有返回值-只需切换到另一个任务。执行器/光纤由低层连接的底层实现管理
——当新连接从“另一端”到达时,它会被包装到光纤中。如果我们打开一个连接,同样,它是在光纤中打开的。请详细说明您提供的接口的要求,“阻塞,但异步”不清楚。使用流的代码是否使用回调/协同路由/光纤/?另外,在您的场景中,谁来管理执行器/光纤?“阻塞,但异步”没有多大意义,在术语上像ConyRadion一样查找。@Zulan。通过“阻塞,但异步”我的意思是,你调用这个方法,它直接返回一些值,没有回调,等等,但在后台,它使用光纤来管理多任务-因此没有创建线程,但一个线程仍然没有被阻塞,即使没有返回值-只需切换到另一个任务。执行器/光纤由低层连接的底层实现管理
——当新连接从“另一端”到达时,它会被包装到光纤中。如果我们打开一个连接,同样,它是在光纤中打开的