C++ boost::asio::async\u读取简单示例上100%的CPU使用率

C++ boost::asio::async\u读取简单示例上100%的CPU使用率,c++,sockets,networking,boost,boost-asio,C++,Sockets,Networking,Boost,Boost Asio,在boost::asio afterasync\u accept()中,socket对象通过如下初始化方式移动到会话对象(该对象处理所有async\u read()调用): std::make_shared<session>(std::move(socket_))->start(); boost::asio::async_read(socket_, ... 然后按照以下步骤从客户端读取数据: std::make_shared<session>(std::move

在boost::asio after
async\u accept()
中,
socket
对象通过如下初始化方式移动到
会话
对象(该对象处理所有
async\u read()
调用):

std::make_shared<session>(std::move(socket_))->start();
boost::asio::async_read(socket_, ...
然后按照以下步骤从客户端读取数据:

std::make_shared<session>(std::move(socket_))->start();
boost::asio::async_read(socket_, ...
一切都很顺利。但当我试图使
async\u read()
不是从
会话对象,而是直接从
async\u accept()
并使用它的
socket
对象时,在客户端连接后,CPU立即提高到100%。为什么?

#include <boost/asio.hpp>
using boost::asio::ip::tcp;

class Server
{
public:
  Server(boost::asio::io_service& io_service,
         const tcp::endpoint& endpoint)    
    : acceptor_(io_service, endpoint),
      socket_(io_service)
  {
    do_accept();
  }

private:
  void do_accept()
  {
    acceptor_.async_accept(socket_,
       [this](boost::system::error_code ec)
       {
         if (!ec) {
           char* buf = new char[5];
           boost::asio::async_read(socket_,
              boost::asio::buffer(buf, 5),
              [this, buf](boost::system::error_code ec, std::size_t)
              {
                if (!ec) {
                  std::cout.write(buf, 5);
                  std::cout << std::endl;
                }
                delete[] buf;
              });
         }
         do_accept();
       });
  }

  tcp::acceptor acceptor_;
  tcp::socket socket_;
};

int main(int argc, char* argv[])
{
  int port = 22222;
  boost::asio::io_service io_service;
  tcp::endpoint endpoint(tcp::v4(), port);
  new Server(io_service, endpoint);
  io_service.run();
}

同样的问题也会在中讨论,因为您在所有地方都使用单个
套接字,所以当连接被接受时,您的处理程序会再次调用do_accept(),它使用相同的
套接字,然后它会被一次又一次地接受

您可能需要始终使用如下所示的新套接字:

  void do_accept()
  {
    boost::shared_ptr<tcp::socket> psocket(new tcp::socket(io_service));
    acceptor_.async_accept(*psocket, boost::bind(&Server::handleAccept, this, psocket, _1));
  }

  void handleAccept(boost::shared_ptr<tcp::socket> psocket, const boost::system::error_code& ec)
  {
    if (!ec) {
    char* buf = new char[5];
    boost::asio::async_read(
      *psocket,
      boost::asio::buffer(buf, 5),
      [this, buf](boost::system::error_code ec, std::size_t)
      {
        if (!ec) {
          std::cout.write(buf, 5);
          std::cout << std::endl;
        }
        delete[] buf;
      });
    }
    do_accept();
  }
void do_accept()
{
boost::shared_ptr psocket(新的tcp::socket(io_服务));
acceptor.async\u accept(*psocket,boost::bind(&Server::handleAccept,this,psocket,_1));
}
void handleAccept(boost::shared\u ptr psocket,const boost::system::error\u code&ec)
{
如果(!ec){
char*buf=新字符[5];
boost::asio::异步读取(
*psocket,
boost::asio::buffer(buf,5),
[this,buf](boost::system::error_code ec,std::size_t)
{
如果(!ec){
标准::可写(buf,5);
std::cout如果传递给的对等套接字未打开,则它将在
async_accept()期间打开
操作。否则,如果对等方已打开,则处理程序将被发布到
io\u服务中进行调用,错误代码为
boost::asio::error::ready\u open
。因此,发布的代码会形成一个紧密的异步调用链:

  • 第一次调用
    async_accept()
    操作,导致打开
    socket
  • async\u accept()
    处理程序调用
    do\u accept()
    ,启动
    async\u accept()
    操作
  • socket\u
    已打开,导致
    async\u accept()
    操作将其处理程序发布到
    io\u服务中,错误为
    boost::asio::error::ready\u open
  • 异步调用链从步骤2开始
  • 官方示例中未观察到此行为,因为会导致moved from对象处于与使用构造函数构造的对象相同的状态。因此,moved from对象处于关闭状态,并准备接受