Heim > Backend-Entwicklung > C++ > Wie verhindert man verschachtelte „async_write'-Aufrufe in Boost Asio?

Wie verhindert man verschachtelte „async_write'-Aufrufe in Boost Asio?

Linda Hamilton
Freigeben: 2024-11-28 01:55:10
Original
939 Leute haben es durchsucht

How to Prevent Interleaved `async_write` Calls in Boost Asio?

So verhindern Sie die Verschachtelung von async_write-Aufrufen in Boost Asio

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.

Problembeschreibung

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.

Lösung: Warteschlangenbasierter Ansatz

Zur Vermeidung Durch die Verschachtelung von async_write-Aufrufen kann ein warteschlangenbasierter Ansatz verwendet werden. So funktioniert es:

  1. Jeder Client verfügt über eine eigene Warteschlange für ausgehende Nachrichten.
  2. Wenn ein Client eine Nachricht sendet, wird diese zur ausgehenden Warteschlange hinzugefügt.
  3. Der Server überprüft die Größe der Ausgangswarteschlange für jeden Client.
  4. Wenn die Warteschlange nicht leer ist, initiiert der Server eine async_write-Vorgang zum Senden der ersten Nachricht in der Warteschlange.
  5. Nach Abschluss des async_write-Vorgangs überprüft der Server die Warteschlange erneut.
  6. Wenn sich weitere Nachrichten in der Warteschlange befinden, wird ein weiterer async_write-Vorgang ausgeführt eingeleitet.
  7. Dieser Vorgang wiederholt sich, bis alle Nachrichten in der Warteschlange gesendet wurden erfolgreich.

Implementierungsbeispiel

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&amp; io_service
            ) :
        _io_service( io_service ),
        _strand( _io_service ),
        _socket( _io_service ),
        _outbox()
    {

    }

    void write( 
            const std::string&amp; message
            )
    {
        _strand.post(
                boost::bind(
                    &amp;Connection::writeImpl,
                    this,
                    message
                    )
                );
    }

private:
    void writeImpl(
            const std::string&amp; message
            )
    {
        _outbox.push_back( message );
        if ( _outbox.size() > 1 ) {
            // outstanding async_write
            return;
        }

        this->write();
    }

    void write()
    {
        const std::string&amp; message = _outbox[0];
        boost::asio::async_write(
                _socket,
                boost::asio::buffer( message.c_str(), message.size() ),
                _strand.wrap(
                    boost::bind(
                        &amp;Connection::writeHandler,
                        this,
                        boost::asio::placeholders::error,
                        boost::asio::placeholders::bytes_transferred
                        )
                    )
                );
    }

    void writeHandler(
            const boost::system::error_code&amp; 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&amp; _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 );
}
Nach dem Login kopieren

Fazit

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!

Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage