boost::asio thread-safety
-
theta schrieb:
Wie sähe es denn mit async_write und async_read aus?
Ja, das ist ok.
Schön, ich glaube es dir.
Hast du den Quellcode untersucht, oder woher beziehst du dein Wissen?Dann läuft async_read nicht über socket::read_some()/receive(), oder doch?
-
theta schrieb:
Ja, das ist sicher. Dennoch... ein nächstes async_write ist erst sinnvoll nach der letzen Completion.
Simon
Nein, ist es nicht. Wenn mehrere Threads explizit auf dem gleichen Socket rumrödeln, muss man synchronisieren. Steht auch in der Doku, bei
ip::<Protokoll>::socketganz unten unter "Thread Safety".
-
Tachyon schrieb:
theta schrieb:
Ja, das ist sicher. Dennoch... ein nächstes async_write ist erst sinnvoll nach der letzen Completion.
Simon
Nein, ist es nicht. Wenn mehrere Threads explizit auf dem gleichen Socket rumrödeln, muss man synchronisieren. Steht auch in der Doku, bei
ip::<Protokoll>::socketganz unten unter "Thread Safety".Aber async_write ist keine Methode des Sockets, sondern eine freie Funktion.
-
Stefan schrieb:
Tachyon schrieb:
theta schrieb:
Ja, das ist sicher. Dennoch... ein nächstes async_write ist erst sinnvoll nach der letzen Completion.
Simon
Nein, ist es nicht. Wenn mehrere Threads explizit auf dem gleichen Socket rumrödeln, muss man synchronisieren. Steht auch in der Doku, bei
ip::<Protokoll>::socketganz unten unter "Thread Safety".Aber async_write ist keine Methode des Sockets, sondern eine freie Funktion.
Und die funktioniert auch so ganz ohne Socket als Argument, ja?
-
Tachyon schrieb:
Stefan schrieb:
Tachyon schrieb:
theta schrieb:
Ja, das ist sicher. Dennoch... ein nächstes async_write ist erst sinnvoll nach der letzen Completion.
Simon
Nein, ist es nicht. Wenn mehrere Threads explizit auf dem gleichen Socket rumrödeln, muss man synchronisieren. Steht auch in der Doku, bei
ip::<Protokoll>::socketganz unten unter "Thread Safety".Aber async_write ist keine Methode des Sockets, sondern eine freie Funktion.
Und die funktioniert auch so ganz ohne Socket als Argument, ja?
Vielleicht ruft async_write/read selbst ja gar keine Methode des Sockets auf. Der Aufruf könnte durchaus thread-safe sein. Leider sagt die Doku darüber nichts.
-
Was meinst Du, wofür der Socket von
async_writebenötigt wird? Nur so zum Spaß?async_writeist re-entrant und benötigt ein Socket-Objekt zur Arbeit, und das ist eben nicht Threadsicher. Glaub es einfach.
-
Tachyon schrieb:
Was meinst Du, wofür der Socket von
async_writebenötigt wird? Nur so zum Spaß?async_writeist re-entrant und benötigt ein Socket-Objekt zur Arbeit, und das ist eben nicht Threadsicher. Glaub es einfach.
async_write() schreibt doch selbst gar nicht auf das Socket, die Funktion kehrt ja immer sofort zurück. Der Schreibvorgang geschieht irgendwo in io_service, unter der Voraussetzung dass run() aufgerufen wurde.
Lies lieber mal selbst die Doku von boost::asio, und täusche nicht Kenntnisse vor die du nicht hast. Trotzdem bin ich dir dankbar dass du in dem Thema postest.
-
Tachyon schrieb:
Was meinst Du, wofür der Socket von
async_writebenötigt wird? Nur so zum Spaß?async_writeist re-entrant und benötigt ein Socket-Objekt zur Arbeit, und das ist eben nicht Threadsicher. Glaub es einfach.
Dann ist sie eben NICHT reentrant. Fachbegriffe nur benützen, wenn man Ahnung hat.

-
Stefan schrieb:
Tachyon schrieb:
Was meinst Du, wofür der Socket von
async_writebenötigt wird? Nur so zum Spaß?async_writeist re-entrant und benötigt ein Socket-Objekt zur Arbeit, und das ist eben nicht Threadsicher. Glaub es einfach.
async_write() schreibt doch selbst gar nicht auf das Socket, die Funktion kehrt ja immer sofort zurück. Der Schreibvorgang geschieht irgendwo in io_service, unter der Voraussetzung dass run() aufgerufen wurde.
Lies lieber mal selbst die Doku von boost::asio, und täusche nicht Kenntnisse vor die du nicht hast. Trotzdem bin ich dir dankbar dass du in dem Thema postest.
Sorry, aber ich arbeite seit 1.36 mit ASIO und bin sich entsprechend lange in der boost-Mailingliste aktiv. Ich kenne mich also durchaus einigermaßen mit Asio aus.
-
@Tachyon:
Theta sagte, async_write() sei thread-safe. Du sagt, es ist es nicht. Aus der Doku lässt sich weder das eine, noch das andere eindeutig ableiten. Vielleicht sollten wir einfach abstimmen?
Aber mal ehrlich: Wenn du so erfahren mit der Library bist, solltest du deine Aussage bezüglich der Threadsicherheit auch nachvollziehbar begründen können, oder nicht? Oder hast du dein Wissen nur vom Hörensagen?Edit:
Zur Präzisierung: Es geht um die Frage ob async_write() und async_read() von unterschiedlichen Threads aufgerufen werden können, ohne den Zugriff auf das Socket zu synchronisieren.
-
Ist doch eigentlich ganz einfach. Du benutzt einen Socket. Ohne den kannst Du nichts senden, da der Socket die Verbindung dar stellt. Die Socket-Objekte von
boost.asiosind explizit NICHT Threadsicher. Das steht, wie bereits gesagt, in der Doku.Wenn Du jetzt bei gehst, und aus mehreren Threads
async_writemit dem gleichen Socket aufrufst, dann ist das ein Problem. Infos über Threadsicherheit müssen für Dinge angegeben werden, die in irgendeiner Form Daten halten welche eben u.U. nicht von mehreren Threads gleichzeitig benutzt werden dürfen - oder eben nicht.Eine Funktion hält im normalfall selbst keine geteilten Daten (zumidnest sollte sie das nicht). Sie benutzt jedoch u.U. (z.B. in Deinem Fall) welche. In diesem Fall Dein Socket. Und Sockets sind, wie oben geschrieben nun mal nicht threadsicher.
Schlussendlich ruftasync_writeübrigens auch nursocket::async_write_someauf. Bei bedarf kannst Du Dich selbst davon überzeugen. Das ist lesbarer Template-Code.Du kannst es ja auch gerne machen wie Du magst. Es sollte nur eine Hilfestellung sein. Ich habe mit
boost.asioso meine Erfahrungen gemacht, und bin dabei auch oft auf die Fresse gefallen, was ich Dir eigentlich ersparen wollte...Das hier...
Stefan schrieb:
Lies lieber mal selbst die Doku von boost::asio, und täusche nicht Kenntnisse vor die du nicht hast. Trotzdem bin ich dir dankbar dass du in dem Thema postest.

...finde ich daher etwas unangemessen.
-
Ich kann mich irren... und das scheint hier der Fall gewesen zu sein.
-
@tachyon:
Du hast völlig recht. async_write() kann aufgrund der Aufrufe von socket::async_write_some() nicht thread-safe sein. Ich war irgendwie zu blöd, das zu realisieren.
Danke für deine Geduld.