Boost Asio による非同期書き込み: インターリーブの防止
問題ステートメント:
アプリケーション内複数のクライアントがメッセージを非同期に送信できる場合、これを防ぐことが重要です。インターリーブによる非同期書き込み操作。これにより、メッセージの順序が間違ったり、データが文字化けしたりする可能性があります。
解決策:
この問題に対する簡単で効果的な解決策は、クライアントごとに送信ボックス キューを実装することです。送信ボックス キューは、送信する必要があるメッセージのバッファとして機能します。
仕組み:
コード例:
以下は、送信ボックス キューの使用法を示す簡略化されたコード例です。書き込みを禁止するインターリーブ:
#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 サイトの他の関連記事を参照してください。