提升asio在读取时占用100%cpu

时间:2009-08-24 03:24:15

标签: c++ boost winapi

我创建了一个使用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 visual c ++ 窗

3 个答案:

答案 0 :(得分:1)

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

Boost文档中有很多examples说明了如何做到这一点,我发现它可以更有效地利用线程和处理器资源。

答案 1 :(得分:0)

你应该避免紧张的循环:

// 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的正确习语。

答案 2 :(得分:0)

考虑使用免费功能,

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