ホームページ > バックエンド開発 > C++ > Asio の非同期書き込みを強化してメッセージ インターリーブを防ぐにはどうすればよいですか?

Asio の非同期書き込みを強化してメッセージ インターリーブを防ぐにはどうすればよいですか?

DDD
リリース: 2024-12-02 02:53:18
オリジナル
604 人が閲覧しました

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

Boost Asio による非同期書き込み: インターリーブの防止

問題ステートメント:

アプリケーション内複数のクライアントがメッセージを非同期に送信できる場合、これを防ぐことが重要です。インターリーブによる非同期書き込み操作。これにより、メッセージの順序が間違ったり、データが文字化けしたりする可能性があります。

解決策:

この問題に対する簡単で効果的な解決策は、クライアントごとに送信ボックス キューを実装することです。送信ボックス キューは、送信する必要があるメッセージのバッファとして機能します。

仕組み:

  1. メッセージのエンキュー:クライアントがメッセージを送信すると、対応する送信トレイに追加されます
  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;
};
ログイン後にコピー

利点:

このアプローチにはいくつかの利点があります:

  • 書き込み操作が指定された順序で実行されることを保証します。
  • 複数からのメッセージのインターリーブを防止します。
  • 複雑な同期メカニズムを回避してコードを簡素化します。

以上がAsio の非同期書き込みを強化してメッセージ インターリーブを防ぐにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート