mutex/multithreading
-
Jud4s schrieb:
wie kann g_m hier g_i beeinflussen? Mit welcher Logik erkennt der Compiler das?
Und was meinst du mit "immer den gleichen mutex locken"?Der Compiler erkennt da gar nix! Zur Laufzeit wird geschaut -> g_m locked? no: exec; yes: wait.
DU bist dafür verantwortlich, dass immer dann wenn g_i verwendet wird, der mutex gelocked ist, und zwar g_m! Wenn du meinst "gut, muss ich locken, mach ich mal neuen mutex g_nm", dann hast du Pech, da niemand deinen mutex verwendet sondern g_m, und dann trotz mutexen gleichzeitiger Zugriff stattfindet!
-
so das jetzt nochmal so das ich es verstehe^^
woher weiß der mutex das er auf g_i aufpassen soll?
Wie soll das funktionieren? Die Logik dahinter?
-
Jud4s schrieb:
woher weiß der mutex das er auf g_i aufpassen soll?
Der Mutex weiß gar nicht, worauf er aufpassen soll! Du musst das wissen, und entsprechend einen (DEN EINEN!) Mutex locken und bitte auch wieder unlocken...
-
ahhh kapiert
danke
-
wär es da nicht eigentlich sinnvoll eine klasse zu erstellen die einer Variable einen mutex zuordnet und diesen Speichert und das jedesmal wenn man eine methode von der Klasse z.b. lock("variablenname) aufruft wird geguckt ob es dafür schon ein mutex gibt der dann gelockt wird oder ggf wird ein neuer erstellt.
Oder gibt es sowas schon bzw ist das nicht sinnvoll?
-
AlexanderKiebler schrieb:
Wenn irgendwo ein Schreibprozess ist, welcher:
boost::recursive_mutex g_m;
nicht lockt, bevor er auf
int g_i
zugreift, funktioniert die synchronisation nicht mehr ??.korrekt
Kurtz, es kann gut sein, dass ein zweiter Prozess in den momentan aktiven kommt
während das Mutex g_m gelockt ist, aber nur dann, wenn er (der unterbrechende Prozess) selber g_m nicht lockt ???Ich verstehe den Satz nicht ganz, bzw. ich denke du verwendest den Begriff "Prozess" da nicht ganz richtig.
Aber egal.
Ein Mutex ist einfach ein "Ding", das immer nur einer (ein Thread) "haben" kann.
Mit "lock" kann man sich dieses Ding nehmen. Hat es schon ein anderer, muss man warten bis dieser es wieder hergibt. Kannst du dir vorstellen wie ne Karte die auf nem bestimmten Tisch liegt wenn sie "frei" ist, bzw. wenn nicht dann hat sie grad irgendwer in der Hand.
Anders gesagt: es ist sichergestellt, dass immer nur ein Thread gleichzeitig eine Mutex "gelockt" haben kann.WENN man sich als Programmierer nun daran hält, dass man immer nur an einer bestimmten Datenstruktur rummacht, während man auch "die zugehörige" Mutex "hält", dann ist damit sichergestellt, dass diese Datenstruktur nie von zwei Threads gleichzeitig bearbeitet wird.
Irgendwelche Automatismen oder Hilfestellungen des Betriebssystems gibt's allerdings keine, d.h. man muss selbst sicherstellen dass dieser "Vertrag" eingehalten wird.
-
Jud4s schrieb:
wär es da nicht eigentlich sinnvoll eine klasse zu erstellen die einer Variable einen mutex zuordnet und diesen Speichert und das jedesmal wenn man eine methode von der Klasse z.b. lock("variablenname) aufruft wird geguckt ob es dafür schon ein mutex gibt der dann gelockt wird oder ggf wird ein neuer erstellt.
Oder gibt es sowas schon bzw ist das nicht sinnvoll?Es gibt ähnliche Ansätze, hat sich aber nicht durchgesetzt.
Der Grund ist denke ich, dass solche Hilfsmittel in Wirklichkeit wohl wenig hilfreich wären. Oftmals (fast immer) schützt man mehrere Variablen über die selbe Mutex, und will auch auf mehrere Variablen gleichzeitig zugreifen nachdem man sich die Mutex geholt hat. Jedesmal in die "Lock" Anweisung 3, 4, 5 Variablennamen mit reinzuschreiben wäre äusserst lästig, und auch einigermassen Fehleranfällig.Und wenn man den Fall hat, dass man gleichzeitig zwei oder mehr Mutexen locken muss, dann muss man verdammt aufpassen, dass man es immer in der selben Reihenfolge macht, sonst hat man schnell einen Deadlock. Und es gibt nur wenige Dinge die lästiger zu Debuggen sind als ein - am besten noch schwer reproduzierbarer - Deadlock.
Und zu guter Letzt: man kann den Code der mit Mutexen rumhantieren muss oft schön in eigene Klassen wegkapseln, so dass der grossteil des Programms sich nicht darum kümmern muss. Und in den Klassen die dann mit Mutexen rumhantieren müssen, ist die Sache oft so klar, dass man keinerlei Hilfe benötigt.
Eine synchronisierte Queue-Klasse z.B. braucht nur eine Einzige Mutex. Alle Zugriffe auf Membervariablen werden über diese Mutex gesteuert, d.h. im Endeffekt holt sich jede Memberfunktion zuerst die Mutex, macht dann was zu tun ist, und gibt sie dann wieder frei.
-
ok danke, bin auch gerade zum Schluss gekommen das mir das zu kompliziert zu programmieren ist für dieses kleine Problem was ich habe
-
Hi hustbaer und Jud4s ,
Also was mich interessieren würde ist Folgendes:boost::recursive_mutex g_m; int g_i = 123; int main1(void) { void foo() { boost::unique_lock<boost::recursive_mutex> lock(g_m); // g_m wird hier gelockt g_i++; } // g_m wird hier wieder freigegeben }
boost::recursive_mutex g_m; int g_i = 123; int main2(void) { void foo() { boost::unique_lock<boost::recursive_mutex> lock(g_m); // g_m wird hier gelockt g_i++; } // g_m wird hier wieder freigegeben }
Also zwei Programme, parallel ausgeführt. Die Variable g_i soll z.B. shared Memory sein. Die Frage:
Ist das Mutex g_m aus der ersten main-funktion (Prozess) gleich dem g_m aus der zweiten ???
Oder gibt es jetzt zwei mutexe mit dem Namen g_m, so wie es eigentlich normal ist. Wenn das der Fall ist, wie mache ich so ein Mutex für beide bekannt ??
In shares Memory darf ich ja keine Objekte erstellen soweit ich das verstanden habe......Kann ich Folgendes Sagen:
-Ein Mutex hat zwei Zustände, offen und geschlossen.
-Ein offenes Mutex kann man schließen.
-Ein Schließen eines geschlossenen Mutex blockiert bis es wieder geöffnet wird.
-Nur der Prozess wo das Mutex geschlossen hat, darf es auch wieder öffnen.Gruß
-
hustbaer schrieb:
@knivil: "ja" auf eine entweder-oder frage ist fesch
Jud4s schrieb:
Wenn ich eine Variable vorm schreiben locke, muss ich sie dann auch locken wenn es eine Lesemethode gibt die parallel laufen könnte?
-
knivil schrieb:
hustbaer schrieb:
@knivil: "ja" auf eine entweder-oder frage ist fesch
Jud4s schrieb:
Wenn ich eine Variable vorm schreiben locke, muss ich sie dann auch locken wenn es eine Lesemethode gibt die parallel laufen könnte?
du nervst.
zitier mal vollständig.Jud4s schrieb:
Wenn ich eine Variable vorm schreiben locke, muss ich sie dann auch locken wenn es eine Lesemethode gibt die parallel laufen könnte? Oder reicht ein lock-aufruf um die Variable für andere Threads zu sperren?
-
AlexanderKiebler schrieb:
Ist das Mutex g_m aus der ersten main-funktion (Prozess) gleich dem g_m aus der zweiten ???
Nein. Dann könnte es ja im ganzen System lediglich einen Mutex geben.
AlexanderKiebler schrieb:
Oder gibt es jetzt zwei mutexe mit dem Namen g_m, so wie es eigentlich normal ist. Wenn das der Fall ist, wie mache ich so ein Mutex für beide bekannt ??
Such mal nach "boost named mutex".
AlexanderKiebler schrieb:
In shares Memory darf ich ja keine Objekte erstellen soweit ich das verstanden habe......
Stimmt so nicht. Das geht prinzipiell schon.
AlexanderKiebler schrieb:
Kann ich Folgendes Sagen:
-Ein Mutex hat zwei Zustände, offen und geschlossen.
-Ein offenes Mutex kann man schließen.
-Ein Schließen eines geschlossenen Mutex blockiert bis es wieder geöffnet wird.
-Nur der Prozess wo das Mutex geschlossen hat, darf es auch wieder öffnen.Richtig.