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, welcheboost::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 einboost::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.