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?
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.
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.
Tags und Links c++ multithreading boost boost-asio