boost::asio::io_service::strand
-
Ich arbeite prinzipiell nur mit manuellen Locking, damit mein Code parallel laufen kann.
-
Ach und nochwas: bei einem Strand können durchaus mehrere Handler parallel laufen, nur eben nicht der gleiche (bzw. alle, die durch denselben Strand geschützt sind). Also wird bei dem Server zwar verhindert, dass der Connect-Handler mehrmals parallel ausgeführt wird, es kann sich aber trotzdem ein Client verbinden und gleichzeitig eine Nachricht bearbeitet werden. Das geht bei nur einem Thread nicht.
trollkenner schrieb:
Es ist doch mittlerweile bekannt das er nur trollen will, da dies ihm am meisten Aufmerksamkeit bringt.
Nö, er leidet bloß an starker Selbstüberschätzung. Aber wir sind ja trotzdem hilfsbereit.
-
314159265358979 schrieb:
Ich arbeite prinzipiell nur mit manuellen Locking, damit mein Code parallel laufen kann.
Bei den Strands geht es nicht darum, dass die Netzwerkfunktionen "parallel" arbeiten (also z.B. das von Dir angesprochene
select), sondern um Deine selbstgeschriebenen Handler.
Der Gag an den Strands ist, dass Du mit nur einem io_service und einem Threadpool, ohne großen Aufwand, sowohl Handler haben kannst, von denen nur jeweils einer aktiv sein kann (diese gehen dann alle durch den gleichen strand), als auch welche, die parallel dazu arbeiten.
Den Strand brauchst Du dann z.B. wenn mehrere asynchrone Operationen parallel auf die gleiche Ressource zugreifen können, z.B. einen Container.
-
Ich weiß schon. Deshalb schreibe ich auch thread-safe Code. Damit ich keine Beschränkung auf 1 Handler habe. Deshalb benutze ich strand auch nicht.

-
314159265358979 schrieb:
Ich weiß schon.
Du weißt offensichtlich nichts...
314159265358979 schrieb:
Deshalb schreibe ich auch thread-safe Code*. Damit ich keine Beschränkung auf 1 Handler habe*. Deshalb benutze ich strand auch nicht.

[] Du hast verstanden, was ich geschrieben habe.
-
Offenbar haben wir ein Kommunikationsproblem.

Erkläre doch mal anders, was du mir sagen willst.
-
314159265358979 schrieb:
Ich weiß schon. Deshalb schreibe ich auch thread-safe Code. Damit ich keine Beschränkung auf 1 Handler habe. Deshalb benutze ich strand auch nicht.

Schonmal daran gedacht, dass der Strand effizienter implementiert werden kann als ein Mutex? Bleiben wir bei dem Beispiel, dass der Connect-Handler synchronisiert werden muss. Nehmen wir an, du hast einen Threadpool mit 4 Threads und benutzt einen Mutex. Wenn sich jetzt gleichzeitig 4 Clients connecten, kann es passieren, dass der Handler in je einem Thread gespawnt wird und dass 3 Handler warten, womit im Endeffekt für kurze Zeit alle Threads blockiert wären.
Wenn du aber einen Strand benutzt, „weiß“ der ioservice, dass der Connect-Handler nicht mehrmals laufen darf und würde ihn gar nicht mehrmals starten. In unserem Beispiel wären also noch 3 Threads frei für andere Handler.
-
Deshalb hält man die Kreuzungspunkte so klein wie möglich. Das dürfte in fast jeden Fall besser sein.
-
314159265358979 schrieb:
Deshalb hält man die Kreuzungspunkte so klein wie möglich. Das dürfte in fast jeden Fall besser sein.
Bitte? Welche Kreuzungspunkte? Ganz ohne Synchronisation wirst du nicht auskommen.
-
314159265358979 schrieb:
Deshalb hält man die Kreuzungspunkte so klein wie möglich. Das dürfte in fast jeden Fall besser sein.
Wenn Du keinen Kreuzungspunkt willst/brauchst, dann benutzt Du für den entsprechenen Handler keinen Strand.
[]Du hast strands verstanden
[x]Du solltest die Finger vonboost.asiolassen.
-
Okay, ich drücke es nochmal anders aus: Man versucht, die Zeit, in der synchronisiert werden muss, möglichst klein zu halten. Kleines Beispiel, direkt aus meinem IRC-Bot Projekt entnommen.
Eine map soll geleert werden in Thread A Hier muss auch noch auf jedes Objekt eine Funktion func aufgerufen werden. Thread B möchte etwas einfügen.
Der ineffiziente Weg:
{ lock_t lock(mtx); for(jedes element in map) elem.func(); map.clear(); }Der bessere Weg:
map tmp; { lock_t lock(mtx); tmp = move(map); } for(jedes element in tmp) elem.func(); // Edit: Destruktor räumt hier ja automatisch auf.
-
314159265358979 schrieb:
Der bessere Weg:
map tmp; { lock_t lock(mtx); tmp = move(map); } for(jedes element in tmp) elem.func(); // Edit: Destruktor räumt hier ja automatisch auf.Äh ja. Ich glaube, es gibt kein denkbares Szenario, wo das irgendetwas bringt.
-
Mit Deadlocks hatte ich jedenfalls noch nie zu kämpfen

In meinem Fall musste nach dem Aufrufen der Funktionen für die Elemente auch noch eine gewisse Zeit gewartet werden, vielleicht ein paar Sekunden.
-
314159265358979 schrieb:
Mit Deadlocks hatte ich jedenfalls noch nie zu kämpfen

In meinem Fall musste nach dem Aufrufen der Funktionen für die Elemente auch noch eine gewisse Zeit gewartet werden, vielleicht ein paar Sekunden.
Deadlocks entstehen ja auch nur, wenn du mehrere Dinge auf einmal locken musst.
-
Öh, ja. Falsches Wort, du hast Recht. Was ich meine, dürfte klar sein.
