微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Boost Asio:在多线程中使用 streambuf 和 async_write 时很奇怪

如何解决Boost Asio:在多线程中使用 streambuf 和 async_write 时很奇怪

我的程序在发送数据时有一个缓冲区。发送小包不要每次都直接调用async_write,尽量让send方法快速返回,使用streambuf作为发送缓冲区,尽量发送大包。

现在遇到的问题是多个线程同时调用send时,小概率对端可能会收到重复的数据包或者乱七八糟的数据。这是我的代码

cdkDragMoved

相关变量定义如下:

void ClientConnection::send(const string* buffer,function<void (bool status)> callback) {
    {
        unique_lock<mutex> lck(*_ioLockPtr);
        ostream os(_sendBufferPtr.get());
        os << *buffer;
    }
    delete buffer;
    callback(true);
    _sendBuffer();
}

void ClientConnection::_sendBuffer() {
    unique_lock<mutex> lck(*_ioLockPtr);

    size_t bufferSize = _sendBufferPtr->size();
    if (!bufferSize || _sendingBufferCount > 0) {
        return;
    }

    ++_sendingBufferCount;
    async_write(*_socketPtr,_sendBufferPtr->data(),boost::asio::transfer_exactly(bufferSize),boost::bind(&ClientConnection::_handleWrite,shared_from_this(),boost::asio::placeholders::error,boost::asio::placeholders::bytes_transferred));

    _sendBufferPtr->consume(bufferSize);
}

void ClientConnection::_handleWrite(const boost::system::error_code& error,size_t bytes_transferred) {
    if (!error) {
        unique_lock<mutex> lck(*_ioLockPtr);

        size_t bufferSize = _sendBufferPtr->size();

        if (bufferSize) {
            async_write(*_socketPtr,boost::asio::placeholders::bytes_transferred));

            _sendBufferPtr->consume(bufferSize);

        } else {
            --_sendingBufferCount;
        }
    } else {
        {
            unique_lock<mutex> lck(*_ioLockPtr);
            --_sendingBufferCount;
        }
        _close();
    }
}

请帮助我了解如何解决这个问题,谢谢!

解决方法

现在遇到的问题是多个线程同时调用send时

根据documentation,这是严格禁止的:

此操作是根据对流的 async_write_some 函数的零次或多次调用来实现的,称为组合操作。程序必须确保在此操作完成之前,流不执行其他写入操作(例如 async_write、流的 async_write_some 函数或任何其他执行写入的组合操作)。

要序列化异步操作,您可能需要使用链。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。