Ich habe meine Anwendung, in der Nachrichten sowohl von Internet-Sockets als auch von Unix-Domain-Sockets gehört und verarbeitet werden. Jetzt muss ich SSL zu den Internet-Sockets hinzufügen, ich habe ein einzelnes Objekt io_service
für alle Sockets in der Anwendung verwendet. Es scheint jetzt, ich muss separate io_service
Objekte für Netzwerk-Sockets und Unix-Domain-Sockets hinzufügen. Ich habe keine Threads in meiner Anwendung und verwende async_send
und async_recieve
und async_accept
, um Daten und Verbindungen zu verarbeiten. Bitte zeigen Sie mir Beispiele, die mehrere io_service
-Objekte mit asynchronen Handlern verwenden.
Die Frage hat einen Grad an Unsicherheit, als ob mehrere io_service
Objekte benötigt werden. Ich konnte nichts in der Referenz Dokumentation oder der Übersicht für finden SSL und UNIX-Domänen-Sockets , die separate io_service
-Objekte verordneten. Unabhängig davon, hier sind ein paar Optionen:
io_service
: Versuchen Sie, ein einzelnes io_service
zu verwenden.
Wenn Sie kein direktes Handle für das Objekt io_service
haben, aber ein Handle für ein Boost.Asio-E / A-Objekt (z. B. einen Socket) haben, kann ein Handle für das verknüpfte io_service
-Objekt sein erhalten durch Aufruf von socket.get_io_service()
.
io_service
: Wenn mehrere io_service
-Objekte erforderlich sind, dedizieren Sie jedem io_service
einen Thread. Dieser Ansatz wird in Boost.Asios HTTP Server 2 verwendet Beispiel.
Eine Konsequenz dieses Ansatzes ist, dass die Anwendung möglicherweise Thread-Sicherheitsgarantien erfordert. Wenn beispielsweise service1
und service2
beide Completion-Handler haben, die message_processor.process()
aufrufen, muss message_processor.process()
entweder Thread-sicher sein oder threadsicher aufgerufen werden.
io_service
: io_service
bietet blockierungsfreie Alternativen zu %Code%. Wo als run()
wird bis blockiert Alle Arbeiten sind abgeschlossen, io_service::run()
führt Handler aus, die zur Ausführung bereit sind und nicht blockieren. Dadurch kann ein einzelner Thread die Ereignisschleife für mehrere io_service::poll()
-Objekte ausführen:
Um eine Tight-Busy-Schleife zu verhindern, wenn keine Handler bereit sind, kann es sinnvoll sein, sie im Ruhezustand hinzuzufügen. Beachten Sie, dass dieser Schlaf eine Latenz bei der Gesamtbehandlung von Ereignissen verursachen kann.
io_service
: Ein interessanter Ansatz ist die Verwendung eines io_service
um Vervollständigungshandler auf ein einzelnes strand
zu übertragen. Dies ermöglicht einen Thread pro io_service
und verhindert gleichzeitig, dass die Anwendung Thread-Sicherheitsgarantien machen muss, da alle Completion-Handler über einen einzigen Dienst posten, dessen Ereignisschleife nur von einem einzelnen Thread verarbeitet wird.
Dieser Ansatz hat einige Konsequenzen:
io_service
ausgeführt werden sollen, über io_service
. strand::wrap()
s, wodurch eine zusätzliche Komplexitätsebene entsteht. Es ist wichtig, den Fall zu berücksichtigen, in dem die sekundäre io_service
keine Arbeit mehr hat und ihre io_service
zurückgibt. Es kommt häufig vor, dass asynchrone Ketten innerhalb desselben run()
auftreten. Daher ist der Dienst nie arbeitslos, da ein Completion-Handler zusätzliche Arbeit auf dem io_service
veröffentlichen wird.
Wenn andererseits ein Strang verwendet wird, um Arbeit an ein anderes io_service
zu übergeben, wird der umhüllte Handler innerhalb von io_service
aufgerufen, was dazu führt, dass er den Beendigungshandler in service2
setzt. Wenn der umhüllte Handler die einzige Arbeit in service1
war, dann hat service2
keine Arbeit mehr und bewirkt, dass service2
zurückkehrt.
Um dies zu berücksichtigen, verwendet der Beispielcode eine servce2.run()
für io_service::work
, so dass service2
so lange blockiert bleibt, bis run()
.
Sieht so aus, als ob Sie einen Server und keinen Client schreiben. Ich weiß nicht, ob das hilft, aber ich verwende ASIO, um mit 6 Servern von meinem Client zu kommunizieren. Es verwendet TCP / IP SSL / TSL. Sie finden einen Link zum Code hier
Sie sollten nur ein io_service-Objekt mit mehreren Socket-Objekten verwenden können. Wenn Sie jedoch entscheiden, dass Sie mehrere io_service-Objekte wirklich haben möchten, sollte es ziemlich einfach sein. In meiner Klasse ist das io_service-Objekt statisch. Entfernen Sie einfach das Schlüsselwort static zusammen mit der Logik im Konstruktor, die nur eine Instanz des io_service-Objekts erstellt. Abhängig von der Anzahl der Verbindungen, die für Ihren Server erwartet werden, wäre es wahrscheinlich besser, einen Thread-Pool zu verwenden, der für die Verarbeitung von Socket-E / A zuständig ist, anstatt für jede neue Socket-Verbindung einen Thread zu erstellen.
Tags und Links boost-asio