boost::asio thread-safety



  • 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>::socket ganz 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>::socket ganz 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_write benötigt wird? Nur so zum Spaß? async_write ist 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_write benötigt wird? Nur so zum Spaß? async_write ist 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_write benötigt wird? Nur so zum Spaß? async_write ist 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_write benötigt wird? Nur so zum Spaß? async_write ist 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.asio sind explizit NICHT Threadsicher. Das steht, wie bereits gesagt, in der Doku.

    Wenn Du jetzt bei gehst, und aus mehreren Threads async_write mit 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 ruft async_write übrigens auch nur socket::async_write_some auf. 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.asio so 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.


Anmelden zum Antworten