>백엔드 개발 >C++ >Boost Asio의 비동기 쓰기는 어떻게 메시지 인터리빙을 방지할 수 있습니까?

Boost Asio의 비동기 쓰기는 어떻게 메시지 인터리빙을 방지할 수 있습니까?

DDD
DDD원래의
2024-12-02 02:53:18582검색

How Can Boost Asio's Asynchronous Writes Prevent Message Interleaving?

Boost Asio를 사용한 비동기 쓰기: 인터리빙 방지

문제 설명:

애플리케이션에서 여러 클라이언트가 비동기적으로 메시지를 보낼 수 있는 경우 비동기 쓰기 작업을 방지하는 것이 중요합니다. 인터리빙. 이로 인해 메시지 순서가 잘못되거나 데이터가 왜곡될 수 있습니다.

해결책:

이 문제에 대한 간단하고 효과적인 해결책은 각 클라이언트에 대해 보낼 편지함 대기열을 구현하는 것입니다. 보낼 편지함 대기열은 전송해야 하는 메시지에 대한 버퍼 역할을 합니다.

작동 방식:

  1. 메시지 대기열에 넣기: 클라이언트가 메시지를 보내면 해당 메시지는 해당 발신함에 추가됩니다. queue.
  2. 쓰기 시작: 보낼 편지함 대기열이 비어 있으면 비동기 쓰기 작업이 시작되어 대기열의 첫 번째 메시지를 보냅니다.
  3. 쓰기 처리 완료: 쓰기 작업이 완료된 후 해당 메시지가 보낼 편지함에서 제거됩니다. queue.
  4. 보내는 편지함 크기 검사: 비동기 쓰기 완료 핸들러는 보낸 편지함 대기열에 남은 메시지가 있는지 확인합니다. 그렇다면 또 다른 비동기 쓰기 작업이 즉시 시작됩니다.

코드 예:

다음은 발신함 대기열을 사용하여 다음 작업을 수행하는 방법을 보여주는 단순화된 코드 예입니다. 쓰기 방지 인터리빙:

#include <boost/asio.hpp>
#include <boost/bind.hpp>

#include <deque>
#include <iostream>
#include <string>

class Connection {
public:
    Connection(boost::asio::io_service& io_service)
        : _io_service(io_service), _strand(io_service), _socket(io_service), _outbox() {}

    void write(const std::string& message) {
        _strand.post(boost::bind(&Connection::writeImpl, this, message));
    }

private:
    void writeImpl(const std::string& message) {
        _outbox.push_back(message);
        if (_outbox.size() > 1) {
            // Outstanding async_write, return
            return;
        }

        this->write();
    }

    void write() {
        const std::string& message = _outbox[0];
        boost::asio::async_write(_socket, boost::asio::buffer(message.c_str(), message.size()),
                                 _strand.wrap(boost::bind(&Connection::writeHandler, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)));
    }

    void writeHandler(const boost::system::error_code& error, const size_t bytesTransferred) {
        _outbox.pop_front();

        if (error) {
            std::cerr << "Could not write: " << boost::system::system_error(error).what() << std::endl;
            return;
        }

        if (!_outbox.empty()) {
            // More messages to send
            this->write();
        }
    }

private:
    typedef std::deque<std::string> Outbox;

private:
    boost::asio::io_service& _io_service;
    boost::asio::io_service::strand _strand;
    boost::asio::ip::tcp::socket _socket;
    Outbox _outbox;
};

이점:

이 접근 방식은 여러 가지 이점을 제공합니다.

  • 쓰기 작업이 순서대로 실행되도록 보장합니다.
  • 여러 메시지가 섞이는 것을 방지합니다.
  • 복잡한 동기화 메커니즘을 피하여 코드를 단순화합니다.

위 내용은 Boost Asio의 비동기 쓰기는 어떻게 메시지 인터리빙을 방지할 수 있습니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.