boost::asio sockets asynchron vs blocking



  • Hi Leute, ich hab ein Problem mit boost::asio.
    In den Beispielen (zb der Chat) wird immer über callbacks gearbeitet (zb beim recieve, accept usw). Ich verstehe aber nicht wie sich das bzgl thread-safety verträgt.
    Angenommen ich habe ein Objekt das einen acceptor hat und das beim accept per std::bind( ) eine methode von sich selbst aufruft das dann den erhaltenen socket auf einer std::list einträgt. Ich frage mich ob das so ohne weiteres möglich ist dann noch von außen auf diese liste zuzugreifen (also generell außerhalb der ge'bind'eten funktion).



  • Nicht so einfach diese Frage ohne Code zu beantworten, denn je nach Code ist es thread-safe oder eben nicht.

    Ev. hilft dir folgendes ein wenig weiter:

    Die Handler (accept, read, write, wait...) werden in Boost.Asio pro boost::asio::io_service nur von Threads aufgerufen, welche boost::asio::io_service::run() aufrufen (oder Varianten davon).

    Wenn du jetzt ein boost::asio::io_service hast, welcher von genau einem Thread getrieben wird (= boost::asio::io_service::run() aufruft), dann werden die Handler immer von diesem einzigen Thread aufgerufen. Wenn keine zusätzlichen Threads involviert sind (was normalerweise nicht der Fall ist), dann ist der Aufbau thread-safe.

    Wenn du mehrere Threads hast, welche den boost::asio::io_service antreiben, muss man mehr überlegen. Nur wenn mehrere Handler auf gemeinsame Daten zugreifen wollen ist eine Synchronisierung nötig. Hier genügt es ein boost::asio::io_service::strand zu verwenden, welcher sicherstellt, dass Handler nicht gleichzeitig aufgerufen werden. Das gilt nur, sofern keine zusätzlichen Threads involviert sind.

    Konkret:

    Angenommen ich habe ein Objekt das einen acceptor hat und das beim accept per std::bind( ) eine methode von sich selbst aufruft das dann den erhaltenen socket auf einer std::list einträgt. Ich frage mich ob das so ohne weiteres möglich ist dann noch von außen auf diese liste zuzugreifen (also generell außerhalb der ge'bind'eten funktion).

    Wenn "von aussen" bedeutet.. von einem anderen Thread als diejenigen, die boost::asio::io_service::run() aufrufen (möglicherweise nur einer), dann ist das nicht thread-safe. Es kommt nicht darauf an, ob das "ausserhalb der ge'bind'eten funktion" stattfindet oder nicht, sondern auf welchem Thread der Zugriff geschieht.

    Besonders bei der 1-Thread Variante hilft dir hier u.U. boost::asio::io_service::post(..) zu benutzen. So transferierst du den Aufruf auf den gewünschten Thread.


Anmelden zum Antworten