Variable als Flag zur Threadsicherheit
-
- Beiträge: 17389
- Registriert: 10.11.2004 03:22
also, um mich nochmal zu wiederholen:
wenn man eine simple variable benutzt, die durch einen pointer repräsentiert wird,
und einen simplen befehl wie b+1 oder b-1, der durch ein einziges ASM-command ausgedrückt wird,
(egal ob es eine addition, ein increment oder ein decrement ist)
dann ist ein MUTEX absolut unnötig.
ein Mutex braucht man nur für komplexere operationen,
wo die CPU-internen sicherheitsvorkehrungen nicht mehr ausreichen.
wenn man eine simple variable benutzt, die durch einen pointer repräsentiert wird,
und einen simplen befehl wie b+1 oder b-1, der durch ein einziges ASM-command ausgedrückt wird,
(egal ob es eine addition, ein increment oder ein decrement ist)
dann ist ein MUTEX absolut unnötig.
ein Mutex braucht man nur für komplexere operationen,
wo die CPU-internen sicherheitsvorkehrungen nicht mehr ausreichen.
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Der Weise weiß, dass er ein Narr ist.
-
- Beiträge: 713
- Registriert: 22.03.2005 00:29
- Computerausstattung: Computer und Strom vorhanden
- Wohnort: LK Wolfenbüttel
Verwechsele was nicht. Ich meine "zeitintensiv" NICHT "rechenintensiv". Zwar ist logisch, das auch das bearbeiten der Threads natürlich die CPUlast hochjagt, aber nicht zwangsweise. Das "zeitintensive" kommt vor allem durch warten auf "event" oder durch "mutex"-Nutzung zustande. Dahe kann es schon sein, das etliche Threads laufen würden ohne das sie Last auslösen.bau also am besten in zeitintensive schleifen ein Delay(0) ein,
damit sich deine threads nicht gegenseitig zu sehr bremsen.
Aber der Hinweis von dir ist grundlegend richtig und das mit der Dauer wenn man Threads startet ist sehr interessant.
1. Win10
PB6.1
PB6.1
- ts-soft
- Beiträge: 22292
- Registriert: 08.09.2004 00:57
- Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel - Wohnort: Berlin
Code: Alles auswählen
Global a.l, b.l, c.l
Mutex1 = CreateMutex()
Mutex2 = CreateMutex()
Mutex3 = CreateMutex()
Ich verstehe es nicht, im Thread gebe ich Mutex1 oder 2 oder 3 an, aber wie
sage ich welcher wenn schützt?
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.

Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.

-
- Beiträge: 713
- Registriert: 22.03.2005 00:29
- Computerausstattung: Computer und Strom vorhanden
- Wohnort: LK Wolfenbüttel
also wie Kaeru Gaman schrieb sind Alle drei Variablen in soweit geschützt, das immer nur ein thread gleichzeitg in sie schreiben kann. da kann nichts passieren, aber halt nur für diesen bruchteil einer Sekunden. ein Mutex ist dazu da um lange Operationen zu schützen, wenn man will STundenlang.
Ach wenn 100 Threads gleichzeitg die Globalen a.l, b.l, c.l beschreiben, stürtzt das Programm nicht ab und es gibt keine Rechenfehler. Ist also Threadsicher. Aber wenn du jetzt einen Flag nutzen willst und sagen wir mal Thread ein will variable a.l ändern und Thread zwei auch, Thread1 aber das nur macht, wenn der Wert bei 1 steht, dann kann man das nur mit Umwegen oder Mutex machen, denn Thread1 liest beispielweise die variable a.l aus, der WErt ist Null, also kann Thread1 den ja um eins hochzählen, aber bevor der nächste Schritt, das addieren ausgeführt wird, kann bereits Thread2 den WErt auf 1 gesetzt haben, nun addiert auch der Thread1 EINS dazu und es kommt zwei raus, obwohl das nie passieren dürfte.
Global a.l, b.l, c.l
Mutex3 = CreateMutex()
du kannst nun mit einem mutex alle variablen schüzten oder für jede einen eigenen nutzen. Es kommt drauf an, was welcher Thread macht.
Egal in welchem Thread du noch eine Ausführung schützen willst und egal wie lange, sobald du lockmutex(mutex1) aufrufst, ist der Code der danach kommt solange geschützt, bis er mit unlockmutex(mutex1) freigegeben wird. Was bewirtk das lock!? ganz einfach ALLE anderen aufrufe von lockmutex(mutex1) (!!!) können ausgeführt werden WARTEN aber solange bis der erste Thread diesen mit unlock freigibt, dann geht die ausführung weiter, aber nur EIN THREAD geht weiter.
Alle anderen Mutex werden nicht betroffen. Wenn ich also lockmutex(mutex1) aufrufen, so stoppen alle andern lockmutex(mutex1) beim aufruf, aber z.B. lockmutex(mutex2) stoppt nicht, sondern läuft weiter.
Du mußt dir das wie eine Gleisanlage vorstellen (besser als Autobahn, da man da ja die Spur wechesln kann), du hast also Beispielweise 3 Gleise nebeneinander, aber nicht verbunden (mutex 1-3) nun soll auf jedem gleis etwas ablaufen, je gleis einige Züge, aber dann steht da ein streckenposten (lockmutex), der läßt nur den ersten Zug durch, alle anderen müssen warten bis der erste Zug weg ist und dann wird der nächste durchgelassen. Was auf den anderen Gleisen passiert interessiert ja nicht.
Aber genau hier kann es bei der Kombination von Mutex zu problemen kommen, denn der Streckenposten von Gleis 2 kann natürlich auch den Zug auf Gleis ein Stoppen wenn er rüber geht, läßt also der erste Streckenposten den nächsten Zug durch, aber der zweite Posten geht es natürlich nicht. Wollte nur mal anmerken das man dann etwas aufpassen muß. Ist vielleicht nicht das beste Bespiel, aber vielleicht hilft das Bildliche etwas, mußte mir das damals auch erst etwas genauer durchdenken.
Ach wenn 100 Threads gleichzeitg die Globalen a.l, b.l, c.l beschreiben, stürtzt das Programm nicht ab und es gibt keine Rechenfehler. Ist also Threadsicher. Aber wenn du jetzt einen Flag nutzen willst und sagen wir mal Thread ein will variable a.l ändern und Thread zwei auch, Thread1 aber das nur macht, wenn der Wert bei 1 steht, dann kann man das nur mit Umwegen oder Mutex machen, denn Thread1 liest beispielweise die variable a.l aus, der WErt ist Null, also kann Thread1 den ja um eins hochzählen, aber bevor der nächste Schritt, das addieren ausgeführt wird, kann bereits Thread2 den WErt auf 1 gesetzt haben, nun addiert auch der Thread1 EINS dazu und es kommt zwei raus, obwohl das nie passieren dürfte.
Global a.l, b.l, c.l
Mutex3 = CreateMutex()
du kannst nun mit einem mutex alle variablen schüzten oder für jede einen eigenen nutzen. Es kommt drauf an, was welcher Thread macht.
Egal in welchem Thread du noch eine Ausführung schützen willst und egal wie lange, sobald du lockmutex(mutex1) aufrufst, ist der Code der danach kommt solange geschützt, bis er mit unlockmutex(mutex1) freigegeben wird. Was bewirtk das lock!? ganz einfach ALLE anderen aufrufe von lockmutex(mutex1) (!!!) können ausgeführt werden WARTEN aber solange bis der erste Thread diesen mit unlock freigibt, dann geht die ausführung weiter, aber nur EIN THREAD geht weiter.
Alle anderen Mutex werden nicht betroffen. Wenn ich also lockmutex(mutex1) aufrufen, so stoppen alle andern lockmutex(mutex1) beim aufruf, aber z.B. lockmutex(mutex2) stoppt nicht, sondern läuft weiter.
Du mußt dir das wie eine Gleisanlage vorstellen (besser als Autobahn, da man da ja die Spur wechesln kann), du hast also Beispielweise 3 Gleise nebeneinander, aber nicht verbunden (mutex 1-3) nun soll auf jedem gleis etwas ablaufen, je gleis einige Züge, aber dann steht da ein streckenposten (lockmutex), der läßt nur den ersten Zug durch, alle anderen müssen warten bis der erste Zug weg ist und dann wird der nächste durchgelassen. Was auf den anderen Gleisen passiert interessiert ja nicht.
Aber genau hier kann es bei der Kombination von Mutex zu problemen kommen, denn der Streckenposten von Gleis 2 kann natürlich auch den Zug auf Gleis ein Stoppen wenn er rüber geht, läßt also der erste Streckenposten den nächsten Zug durch, aber der zweite Posten geht es natürlich nicht. Wollte nur mal anmerken das man dann etwas aufpassen muß. Ist vielleicht nicht das beste Bespiel, aber vielleicht hilft das Bildliche etwas, mußte mir das damals auch erst etwas genauer durchdenken.
1. Win10
PB6.1
PB6.1
- NicTheQuick
- Ein Admin
- Beiträge: 8807
- Registriert: 29.08.2004 20:20
- Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti - Wohnort: Saarbrücken
-
- Beiträge: 713
- Registriert: 22.03.2005 00:29
- Computerausstattung: Computer und Strom vorhanden
- Wohnort: LK Wolfenbüttel
genau sowas bräuchte ich auch. Neben dem Zeitverbrauch/Prozessorlaust durch viel erstellen von Mutex, ist das auch ein Grund warum ich Flags oder "damals" die ASM-Vorlage zur Critical_Section nutze, damit kann man das machen. Ich habe mit der ASM-Vorlage zu CS sowas gemacht, aber bei den PB-Mutex fehlt mir auch sowas. Dann könnte man die Wartezeit sinnvoll ausnutzen. W
Ich wäre auch für sowas.
Ich wäre auch für sowas.
1. Win10
PB6.1
PB6.1
- ts-soft
- Beiträge: 22292
- Registriert: 08.09.2004 00:57
- Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel - Wohnort: Berlin
Wäre nett, wenn mir jemand die Frage: Welcher Mutex schützt b.l ?
von etwas hier drüber noch beantworten würde. Ich blicke es immer noch
nicht
von etwas hier drüber noch beantworten würde. Ich blicke es immer noch
nicht

PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.

Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.

- remi_meier
- Beiträge: 1078
- Registriert: 29.08.2004 20:11
- Wohnort: Schweiz
Vielleicht hilft das hier:
So wie der Code jetzt ist, kann b nur von einem Thread modifiziert
werden, a und c sind während dessen frei für andere Threads.
Wenn in die CriticalSection "Mutex2" eingetreten wird, dann können
a und c nur von diesem Thread modifiziert werden, b ist frei für andere
Threads.
So lange ein Thread nicht in eine CS kann, wartet er.
Ein Mutex signalisiert einfach, ob ich jetzt dieses Objekt verändern darf.
Welches Objekt das ist, musst du selbst entscheiden. Du könntest auch
alle Objekte mit einem einzigen Mutex schützen, aber das könnte ev.
zu einer krassen Verlangsamung deines Programms kommen, da so
immer alle Objekte blockiert wären, wenn ein Thread auch nur ein Objekt
modifizieren möchte.
Es kann sich einfach nur EIN Thread in einer CriticalSection befinden.
Ein zweiter Thread kann erst rein, wenn kein Thread mehr drin ist.
Code: Alles auswählen
Global a.l, b.l, c.l
Global Mutex1 = CreateMutex()
Global Mutex2 = CreateMutex()
Procedure Thread(d.l)
Repeat
LockMutex(Mutex1)
; Mutex1 schützt einfach mal b
b = Sin(b)
UnlockMutex(Mutex1)
LockMutex(Mutex2)
; Mutex2 schützt einfach mal a und c
c = Tan(c)
a = Cos(a)
UnlockMutex(Mutex2)
Delay(0)
ForEver
EndProcedure
a = 4
b = 6
c = 7
For z = 0 To 100
CreateThread(@Thread(), 0)
Next
Repeat
Delay(10)
Until GetAsyncKeyState_(#VK_ESCAPE)
werden, a und c sind während dessen frei für andere Threads.
Wenn in die CriticalSection "Mutex2" eingetreten wird, dann können
a und c nur von diesem Thread modifiziert werden, b ist frei für andere
Threads.
So lange ein Thread nicht in eine CS kann, wartet er.
Ein Mutex signalisiert einfach, ob ich jetzt dieses Objekt verändern darf.
Welches Objekt das ist, musst du selbst entscheiden. Du könntest auch
alle Objekte mit einem einzigen Mutex schützen, aber das könnte ev.
zu einer krassen Verlangsamung deines Programms kommen, da so
immer alle Objekte blockiert wären, wenn ein Thread auch nur ein Objekt
modifizieren möchte.
Es kann sich einfach nur EIN Thread in einer CriticalSection befinden.
Ein zweiter Thread kann erst rein, wenn kein Thread mehr drin ist.
- ts-soft
- Beiträge: 22292
- Registriert: 08.09.2004 00:57
- Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel - Wohnort: Berlin
Alle Variablen, die zwischen LockMutex und UnlockMutex verwendet werden,
sind geschützt, nicht genutzte Variablen kann ich z.B. mit einem anderem
Mutex schützen.
Ich hoffe jetzt hab ich das Prinzip, da könnte die Hilfe sich aber auch mal äußern
Danke
Thomas
sind geschützt, nicht genutzte Variablen kann ich z.B. mit einem anderem
Mutex schützen.
Ich hoffe jetzt hab ich das Prinzip, da könnte die Hilfe sich aber auch mal äußern

Danke
Thomas
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.

Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
