Wann muss ich boost :: asio: strang verwenden

7

Wenn ich das Dokument von boost :: asio lese, ist es immer noch nicht klar, wann ich asio :: strang benutzen muss. Angenommen, ich habe einen Thread mit io_service, ist es dann sicher, wie folgt auf einen Socket zu schreiben?

%Vor%

Wo mehrere Threads Connection :: write (..) aufrufen oder muss ich asio :: strand verwenden?

    
user2004360 06.05.2013, 11:13
quelle

2 Antworten

17

Kurze Antwort: Nein, Sie müssen in diesem Fall kein strand verwenden.

Grob vereinfacht enthält ein io_service eine Liste von Funktionsobjekten (Handlern). Handler werden in die Liste aufgenommen, wenn post() für den Service aufgerufen wird. z.B. Immer wenn eine asynchrone Operation abgeschlossen ist, werden der Handler und seine Argumente in die Liste aufgenommen. io_service::run() führt einen Handler nach dem anderen aus. Wenn also nur ein Thread in Ihrem Fall run() like aufruft, gibt es keine Synchronisationsprobleme und keine strand s werden benötigt.
Nur wenn mehrere Threads run() für dieselbe io_service aufrufen, werden mehrere Handler gleichzeitig in N Threads bis zu N Concurrent Handlern ausgeführt. Wenn das ein Problem ist, z.B. Wenn sich gleichzeitig zwei Handler in der Warteschlange befinden, die auf dasselbe Objekt zugreifen, benötigen Sie strand .
Sie können strand als eine Art Sperre für eine Gruppe von Handlern sehen. Wenn ein Thread einen Handler ausführt, der einem strand zugeordnet ist, wird dieser strand gesperrt, und er wird freigegeben, nachdem der Handler fertig ist. Jeder andere Thread kann nur Handler ausführen, die keinem gesperrten strand zugeordnet sind.

Vorsicht: Diese Erklärung mag übermäßig vereinfacht und technisch nicht korrekt sein, aber es gibt ein grundlegendes Konzept dessen, was in io_service und% co_de passiert % s.

    
Arne Mertz 06.05.2013 11:51
quelle
2

Das Aufrufen von io_service::run() aus nur einem Thread führt dazu, dass alle Ereignishandler innerhalb des Threads ausgeführt werden, unabhängig davon, wie viele Threads Connection::write(...) aufrufen. Daher ist es ohne eine gleichzeitige Ausführung von Handlern sicher. Die Dokumentation bezieht sich darauf als ein impliziter Strang .

Wenn andererseits mehrere Threads io_service::run() aufrufen, wird ein Strang benötigt. Diese Antwort deckt die Stränge viel detaillierter ab.

    
Tanner Sansbury 09.05.2013 19:04
quelle