sockets - 使用 boost::asio async_read_some 的高 CPU 和内存消耗

标签 sockets network-programming boost-asio asyncsocket

我制作了一个从客户端读取数据的服务器,我使用 boost::asio async_read_some 来读取数据,我制作了一个处理函数,这里 _ioService->poll() 将运行事件处理循环来执行准备好的处理程序。在处理程序 _handleAsyncReceive 中,我正在释放在 receiveDataAsync 中分配的 buf。缓冲区大小为 500。
代码如下:

bool 
TCPSocket::receiveDataAsync( unsigned int bufferSize )
{
    char *buf = new char[bufferSize + 1];

    try
    {
        _tcpSocket->async_read_some( boost::asio::buffer( (void*)buf, bufferSize ), 
                                     boost::bind(&TCPSocket::_handleAsyncReceive, 
                                                    this,
                                                    buf,
                                                    boost::asio::placeholders::error,
                                                    boost::asio::placeholders::bytes_transferred) );

            _ioService->poll();

    }
    catch (std::exception& e)
    {
        LOG_ERROR("Error Receiving Data Asynchronously");
        LOG_ERROR( e.what() );
        delete [] buf;
        return false;
    }

    //we dont delete buf here as it will be deleted by callback _handleAsyncReceive
    return true;
}


void 
TCPSocket::_handleAsyncReceive(char *buf, const boost::system::error_code& ec, size_t size)
{
    if(ec)
    {
        LOG_ERROR ("Error occurred while sending data Asynchronously.");
        LOG_ERROR ( ec.message() );
    }
    else if ( size > 0 )
    {
        buf[size] = '\0';
        LOG_DEBUG("Deleting Buffer");
        emit _asyncDataReceivedSignal( QString::fromLocal8Bit( buf ) );
    }
    delete [] buf;
}

这里的问题是与释放相比,缓冲区的分配速度要快得多,因此内存使用量将以指数速率增长,并且在某个时间点它将消耗所有内存,系统将卡住。 CPU 使用率也将在 90% 左右。如何减少内存和 CPU 消耗?

最佳答案

你有内存泄漏。 io_service 轮询 不保证它与发送您的 _handleAsyncReceive .它可以调度其他事件(例如接受),因此您的内存在 char *buf丢失了。我猜你在打电话 receiveDataAsync来自一个循环,但它不是必需的 - 在任何情况下都会存在泄漏(具有不同的泄漏速度)。

如果你关注 asio examples 会更好并使用建议的模式而不是自己制作。

关于sockets - 使用 boost::asio async_read_some 的高 CPU 和内存消耗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15227520/

相关文章:

c++ - 从 Boost Asio 运行 HTTP 服务器示例

c++ - Boost-Beast 异步网络套接字服务器-客户端异步读写不在控制台上写入输出

Python 多处理 TLS 套接字服务器

c - 通过 BSD 套接字在 SSH 上进行身份验证

java - Android Socket 就绪检测?

c - 如何区分p2p网络中运行在同一台机器上的节点,C语言的socket

c - MPLS报头解析

java - 基本 java net 客户端返回 400

php - 一步一步: How to do Xdebug troubleshooting connection to client IDE

c++ - 可能是 boost ssl 握手函数有一些内存泄漏