分散システムでは、クライアントがサーバーにメッセージを非同期に送信するのが一般的です。受信メッセージを処理するために、サーバーは通常、メッセージが受信順に順次処理されるキューベースのメカニズムを実装します。ただし、特定のシナリオでは、メッセージがインターリーブされ、予期しない動作が発生する可能性があります。
複数のクライアントからメッセージを同時に受信するサーバーが関係するシナリオを考えてみましょう。各クライアントのメッセージは、async_write を使用して非同期的に処理されます。クライアントが速いペースでメッセージを送信する場合、async_write 呼び出しがインターリーブされ、メッセージが順番どおりに処理されない可能性があります。
これを防ぐにはasync_write 呼び出しのインターリーブでは、キューベースのアプローチを採用できます。その仕組みは次のとおりです。
次のコード スニペットは、このキューベースのアプローチを実装する方法を示しています。
// Include necessary headers #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; } 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; }; int main() { boost::asio::io_service io_service; Connection foo( io_service ); }
キューベースのアプローチを実装すると、async_write 呼び出しのインターリーブを効果的に防止でき、メッセージが正しい順序で処理されることが保証されます。これは、メッセージ処理の順序がシステムの全体的な機能に大きな影響を与えるシナリオでは特に重要です。
以上がBoost Asio でインターリーブされた `async_write` 呼び出しを防ぐ方法は?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。