2016-05-09 8 views
3

Ich bin nicht sehr vertraut mit asynchronen Programmierung und ich habe eine Frage.Boost.asio und asynchrone Kette, unique_ptr?

Meine Frage ist die folgende. Gegeben hier das echo_server Beispiel für C++ 11 in Boost.Asio: http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/example/cpp11/spawn/echo_server.cpp

Ich möchte wissen, ob die std::make_shared<session> kann in C++ 14 mit einem std::unique_ptr<session> in C++ 14 ersetzt werden, die Vermeidung der Kopfreferenz Anzahl.

Ich bin nicht sicher, da wir shared_from_this() haben, aber nicht so etwas wie unique_from_this(), so wie kann ich auf die unique_ptr<session> von innen this?.

+0

Sie wissen, dass der Overhead ein einzelner Zeiger für zusätzlichen Speicher pro Instanz und eine Referenzzählerschwelle beim Erstellen und Löschen von gemeinsam genutzten Ptrs ist - ansonsten entspricht er genau einem normalen Zeiger. Es ist auch nicht klar, auf welches shared_ptr du dich beziehst, da es in diesem Beispiel mehrere gibt. – xaxxon

+2

Das Konzept eines "unique_from_this" macht nicht einmal Sinn. Sie können nicht einfach einen eindeutigen Zeiger auf eine Speicheradresse erstellen, da Sie eine Race-Bedingung haben, wer den Speicher bereinigt hat. – xaxxon

Antwort

2

Nein, die Verwendung von shared_ptr in asio Programmierung ist idiomatisch.

Die Idee ist, dass die Anzahl der ausstehenden Handler mit der gemeinsamen Anzahl der Objekte übereinstimmt, die die asynchronen Operationen initiieren. Dies wird erreicht, indem eine Kopie des shared_ptr, das das Objekt in den Handler-Funktionsobjekten verwaltet, gebunden wird.

Die C++ 11/14 Weg wäre, die boost::shared_ptr durch std::shared_ptr (std::bind, Lambdas, etc auch perfekt funktionieren mit asio) zu ersetzen.

Update jetzt, dass ich völlig verstehe die Frage:

Im Beispiel Sie verbunden sind, nehme ich es, dass Sie mit dem Shared_ptr genannten Selbst sich beziehen, die in dem Verfahren gehen() erzeugt wird? Sie könnten es ohne shared_ptr schreiben, wenn Sie wollten. Sie müssten dies als letzte Zeile von go() löschen. Sie müssen auch daran denken, alle Ausnahmen abzufangen, um sicherzustellen, dass dieser Codepfad verwendet wurde. Ein unique_ptr könnte dazu natürlich eingerichtet werden, aber dann gibt es ein Lifetime-Management-Problem zwischen dem Aufbau der Session und der erfolgreichen Erstellung des adoptierenden unique_ptr. shared_ptr erleichtert die Verwaltungslast für die Kosten einer atomaren ...

In diesem Fall ist die Antwort streng "ja", aber ich werde es empfehlen, da es spröder ist.

+0

So wie ich es verstehe, wird Ihr Session-Objekt nacheinander eine Pipeline von Handlern durchlaufen.Der Status Ihrer Sitzung wird niemals geteilt. Warum würde ein unique_ptr keinen Sinn ergeben? Der Punkt ist, dass wenn der letzte Handler beendet ist, der Speicher freigegeben wird. Stimmt das? –

+0

Spätestes oder letztes? Wenn es irgendwelche ausstehenden Handler gibt, die die Sitzung betreffen, werden sie schließlich alle feuern (selbst wenn sie abgebrochen werden, wenn der Sockel zerstört wird). Sie können eine manuelle Zählung von ausstehenden Handlern behalten und Ihre Sitzung löschen, wenn sie Null erreicht, aber warum? Das shared_ptr macht genau das mit fast keinem Overhead. –

+0

Wenn es eine Sitzung gibt, gibt es noch Arbeit in Asios Schleife. Es wird nicht beendet. Wenn ich also nicht falsch liege, ist Folgendes der Fall: Wenn Sie unique_ptrs für jede Sitzung verwenden, wird die Schleife beendet, wenn keine Arbeit mehr stattfindet. Ich stimme zu, dass der Overhead niedrig sein kann, das ist eher eine theoretische Frage :) –

0

Wie ich es verstehe, wird Ihr Session-Objekt eine Pipeline von Handlern nacheinander durchlaufen. Der Status Ihrer Sitzung wird niemals geteilt. Warum würde ein unique_ptr keinen Sinn ergeben? Der Punkt ist, dass wenn der letzte Handler beendet ist, der Speicher freigegeben wird. Stimmt das?

Ja, das ist der Trick. Die Bibliothek wurde um kopierfähige Vervollständigungshandler entworfen.

Wenn Sie sich um Overhead kümmern, vermeiden Sie in der Tat shared_ptr.

In diesem Fall tragen Sie einfach einen Verweis auf einen Zustand mit extern gesteuerter Lebensdauer. Stellen Sie nur sicher, dass es am Leben bleibt (genau wie Sie es mit dem io_service-Objekt selbst tun).

+0

Ich verstehe das, aber das antwortet nicht meine ursprüngliche Frage, die ist: kann ich ein unique_ptr verwenden und ein unique_pr, das automatisch durchgeführt wird, bis die Sitzung selbst stirbt? –

+0

Wenn Sie es verstanden haben, warum [haben Sie gefragt] (http://stackoverflow.com/questions/37109220/boost-asio-and-asynchronous-chain-unique-ptr/37109892?noredirect=1#comment61761197_37109300)? Ich weiß auch nicht, wie ich klarer antworten soll. [Ist 'std :: unique_ptr' kopierbar? (Http://en.cppreference.com/w/cpp/memory/unique_ptr)? Wenn nicht, dann ist es nicht möglich, sie in Completion-Handlern direkt zu verwenden, und es wird bestenfalls ein Kludge sein, wenn sie mit Indirection "tapeziert" werden. Mein Rat ist in meiner Antwort. – sehe

+0

In C++ 14 können Sie [my_ptr = move (my_ptr)] erfassen, aber ich habe mich gefragt, ob es noch Probleme gibt. Am meisten besorgt über "unique_from_this()' "oder ähnlich, also habe ich mich gefragt, ob dies wirklich möglich ist: Ersetzen durch unique_ptr und etwas ähnliches. –