2012-05-23 10 views
5

Mein Code verwendet boost :: asio und io_service in einem einzigen Thread, um verschiedene Socket-Operationen durchzuführen. Alle Operationen sind asynchron und jeder Handler hängt von boost::system::error_code (insbesondere boost::asio::error::operation_aborted) ab, um das Ergebnis der Operation zu bestimmen.boost :: asio async-Handler, die nach Abbruch ohne Fehler aufgerufen wurden

Es funktioniert einwandfrei, bis ich die Logik geändert habe, um mehrere gleichzeitige Verbindungen zu machen und den schnellsten auszuwählen. Das heißt, wenn der erste async_read_some Handler ausgelöst wird, storniere ich andere Sockets (shutdown, close - alles) und fahre mit dem aktuellen fort. In 95% der Fälle werden die Lese-Handler anderer Sockets mit dem Fehler operation_aborted aufgerufen. Manchmal werden diese Lese-Handler jedoch ohne Fehler aufgerufen und sagen mir, dass sie erfolgreich N Bytes empfangen haben.

Aber die Dokumentation für die Socket :: cancel() states:

Mit dieser Funktion werden alle ausstehenden asynchronen Verbindung, senden und empfangen Operationen unverzüglich zu beenden und die Handler für abgebrochen wird sich die übergeben werden boost::asio::error::operation_aborted Fehler.

Also, die Fragen: Kann ich wirklich auf den operation_aborted Fehler im Produktionscode verlassen? Wenn ich kann, ist es ein Fehler in Asio von Boost 1.46.1? Wenn ich das nicht kann, gibt es dafür offizielle Dokumente?

+1

Es scheint in Ihrem Fall, dass mehrere Handler "erfolgreich" waren, bevor der Abbruch aufgerufen wurde. Sie können sich darauf verlassen, dass das 'operation_aborted' an alle Handler übergeben wird, die noch nicht ausgeführt wurden (und auf den Aufruf warten). – Chad

Antwort

11

Ok, die Antworten:

  1. Nein, ich kann nicht nur auf die operation_aborted Fehler verlassen.
  2. Natürlich ist es kein Fehler in Asio, nur ein Mangel an Erfahrung auf meiner Seite.
  3. Es gibt ein wenig von offiziellen documentation. Es ist für Timer, nicht die Steckdosen, die jedoch die gleichen Grundsätze gelten:

Wenn der Timer bereits abgelaufen ist, wenn (Abbrechen) aufgerufen wird, dann die Handler für asynchrone Warteoperationen werden:

  • wurden bereits aufgerufen; oder
  • wurden in naher Zukunft für den Aufruf in die Warteschlange gestellt.

Im Grunde war ich in Annahme falsch, wenn ich einen einzigen Thread für io_service verwenden, dann wird jeder Betrieb blockiert werden, während einige Handler ausführen.

Das Verhalten, das ich berichte, macht wirklich viel Sinn und es scheint, dass jeder, der Asio benutzt, das weiß.Ich habe die Mailinglisten von Asio durchforstet und eine Menge Diskussionen über das Thema here, here, here und here gefunden.

Zum Beispiel kann ein Schreibvorgang kann erfolgreich abgeschlossen werden, während Sie in einem Handler sind, aber bevor Sie haben sich herumgesprochen zu rufen Buchse abbrechen, wodurch dessen Abschluss-Handler in die Warteschlange geschrieben werden. Wie ich es verstehe, ist der Fehlercode durch den Status der Operation, die abgeschlossen wurde, nicht den Zustand des Sockets zu dem Zeitpunkt der Handler aus der Warteschlange abgeholt und ausgeführt wird bestimmt.

+1

+1 für die saubere Antwort auf Ihre eigene Frage –

2

Betrachten Sie zwei Verbindungen zur gleichen Zeit. Beide Handler werden ausgelöst, einer wird zuerst behandelt, der zweite wird in der Warteschlange (oder wird in einem anderen Thread behandelt). Man kann sich mehr Beispiele vorstellen.

Um Ihre Anforderung zu implementieren, benötigen Sie ein bisschen mehr Logik.