In verteilten Systemen ist es üblich, dass Clients Nachrichten asynchron an Server senden. Um eingehende Nachrichten zu verarbeiten, implementieren Server normalerweise einen warteschlangenbasierten Mechanismus, bei dem Nachrichten nacheinander in der Reihenfolge ihres Eingangs verarbeitet werden. Es gibt jedoch bestimmte Szenarien, in denen Nachrichten verschachtelt werden können, was zu unerwartetem Verhalten führt.
Stellen Sie sich ein Szenario vor, bei dem ein Server Nachrichten von mehreren Clients gleichzeitig empfängt. Die Nachrichten jedes Clients werden asynchron mit async_write verarbeitet. Wenn die Clients Nachrichten in hoher Geschwindigkeit senden, ist es möglich, dass die async_write-Aufrufe verschachtelt werden, was dazu führt, dass Nachrichten nicht in der richtigen Reihenfolge verarbeitet werden.
Zur Vermeidung Durch die Verschachtelung von async_write-Aufrufen kann ein warteschlangenbasierter Ansatz verwendet werden. So funktioniert es:
Der folgende Codeausschnitt zeigt, wie dieser warteschlangenbasierte Ansatz implementiert wird:
// 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 ); }
Von Durch die Implementierung eines warteschlangenbasierten Ansatzes kann die Verschachtelung von async_write-Aufrufen wirksam verhindert werden, wodurch sichergestellt wird, dass Nachrichten in der richtigen Reihenfolge verarbeitet werden. Dies ist besonders wichtig in Szenarien, in denen die Reihenfolge der Nachrichtenverarbeitung einen erheblichen Einfluss auf die Gesamtfunktionalität des Systems hat.
Das obige ist der detaillierte Inhalt vonWie verhindert man verschachtelte „async_write'-Aufrufe in Boost Asio?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!