Rumah >pembangunan bahagian belakang >C++ >Bagaimana untuk Mencegah Panggilan `async_write` Berjalin dalam Boost Asio?
Dalam sistem yang diedarkan, adalah perkara biasa bagi pelanggan untuk menghantar mesej kepada pelayan secara tidak segerak. Untuk mengendalikan mesej masuk, pelayan biasanya melaksanakan mekanisme berasaskan baris gilir di mana mesej diproses secara berurutan mengikut susunan ia diterima. Walau bagaimanapun, terdapat senario tertentu di mana mesej boleh dijalin, membawa kepada gelagat yang tidak dijangka.
Pertimbangkan senario yang melibatkan pelayan yang menerima mesej daripada berbilang pelanggan secara serentak. Setiap mesej pelanggan diproses secara tak segerak menggunakan async_write. Jika pelanggan menghantar mesej pada kadar yang pantas, panggilan async_write mungkin menjadi bersilang, mengakibatkan mesej diproses tidak teratur.
Untuk mengelakkan interleaving panggilan async_write, pendekatan berasaskan baris gilir boleh digunakan. Begini caranya:
Coretan kod berikut menunjukkan cara melaksanakan pendekatan berasaskan baris gilir ini:
// 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 ); }
Oleh melaksanakan pendekatan berasaskan baris gilir, interleaving panggilan async_write boleh dihalang dengan berkesan, memastikan bahawa mesej diproses dalam susunan yang betul. Ini amat penting dalam senario di mana susunan pemprosesan mesej mempunyai kesan yang ketara ke atas kefungsian keseluruhan sistem.
Atas ialah kandungan terperinci Bagaimana untuk Mencegah Panggilan `async_write` Berjalin dalam Boost Asio?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!