【问题标题】:boost asio taking 100% cpu on read提升 asio 在读取时占用 100% cpu
【发布时间】:2009-11-10 02:11:56
【问题描述】:

我制作了一个使用 boost asio 的套接字应用程序,但是当我尝试从套接字读取任何内容时,它似乎占用了很多 CPU。

Atm 我使用了一个包装类,所以我不必在我的头文件中公开 boost 头文件,看起来像这样:

class SocketHandle
{
public:
    SocketHandle()
    {
        m_pSocket = NULL;
        m_pService = NULL;
    }

    ~SocketHandle()
    {
        delete m_pSocket;
        delete m_pService;
    }

    void connect(const char* host, const char* port)
    {
        if (m_pSocket || m_pService)
            return;

        m_pService = new boost::asio::io_service();

        tcp::resolver resolver(*m_pService);
        tcp::resolver::query query(tcp::v4(), host, port);
        tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
        tcp::resolver::iterator end;

        m_pSocket = new tcp::socket(*m_pService);

        boost::system::error_code error = boost::asio::error::host_not_found;

        while (error && endpoint_iterator != end)
        {
            (*m_pSocket).close();
            (*m_pSocket).connect(*endpoint_iterator++, error);
        }

        if (error)
            throw ...
    }

    tcp::socket* operator->()
    {
        return m_pSocket;
    }

private:
     tcp::socket *m_pSocket;
     boost::asio::io_service *m_pService;
};

然后我像这样从套接字读取:

size_t recv(char *data, size_t size)
{
    boost::system::error_code error;
    size_t len = (*m_pSocket)->read_some(boost::asio::buffer(data, size), error);

    if (error)
               throw ...

    return len;
}

我做错了吗?有没有更好的方法从套接字读取数据?

提升 1.39.0 视觉 C++ 窗户

【问题讨论】:

    标签: c++ boost winapi


    【解决方案1】:

    您可能希望考虑的一项更改(我强烈推荐)是使您的套接字调用异步。这样您就不必担心线程被阻塞或任何套接字调用在内部旋转(我怀疑这可能是您所看到的)。相反,您只需提供一个回调,该回调将接收任何错误和接收的字节数。

    Boost 文档中有很多 examples 说明了如何执行此操作,我发现它有助于更​​有效地使用线程和处理器资源。

    【讨论】:

      【解决方案2】:

      你应该避免紧的while循环:

      // BAD.
      while (error && endpoint_iterator != end)
      {
          (*m_pSocket).close();
          (*m_pSocket).connect(*endpoint_iterator++, error);
      }
      

      尝试类似的方法:

      try
      {
          (*m_pSocket).connect(*endpoint_iterator++, error);
          // ...
      }
      catch (std::exception& ex)
      {
          // Release resources, then try connecting again.
      }
      

      另请参阅examples 以了解使用 Asio 的正确习惯。

      【讨论】:

      • 这是来自 boost asio 示例:P
      【解决方案3】:

      考虑改用free函数,

      size_t len = asio::read(*m_pSocket,asio::buffer(data, size), error);
      

      【讨论】:

      • 为什么?有什么区别吗?
      猜你喜欢
      • 1970-01-01
      • 2012-12-29
      • 1970-01-01
      • 1970-01-01
      • 2022-12-15
      • 2011-11-26
      • 2013-05-01
      • 1970-01-01
      • 2011-11-09
      相关资源
      最近更新 更多