[definitiv Bug] TryLockMutex(Mutex) und LockMutex(Mutex)
-
- Beiträge: 713
- Registriert: 22.03.2005 00:29
- Computerausstattung: Computer und Strom vorhanden
- Wohnort: LK Wolfenbüttel
[definitiv Bug] TryLockMutex(Mutex) und LockMutex(Mutex)
[edit]Bugmeldung für Freak im achten Beitrag (06 Feb 2006 21:56:41)
[/edit]
Hi,
wie soll den TryLockMutex(Mutex) genau funktionieren, habe das wohl nicht ganz verstanden und wie soll sich darauf dann LockMutex(Mutex) verhalten.
TryLockMutex(Mutex) soll doch wenn vorhanden den mutex "verriegeln".
Das tut es zwar wohl auch, aber es liefert IMMER nur NULL zurück, das sollte denke ich nicht sein, oder? "otherwise" steht da doch.
Die Funktion TryLockMutex(Mutex) an sich ist sehr sinnvoll, vor allem in kombination mit LockMutex(Mutex), aber damit funktioniert es nicht so richtig bzw. sinnvoll. zwar verriegelt TryLockMutex(Mutex) den codeteil dann für "LockMutex(Mutex)", aber umgekehrt (leider) nicht. das TryLockMutex(Mutex) verriegelt kann ja nur sinnvoll sein, wenn "lockmutex" nicht gleichzeitig mit einem TryLockMutex(Mutex) laufen darf. aber das passiert ja doch, denn wenn lockmutex verriegelt gilt dies leider nicht für TryLockMutex(Mutex).
TryLockMutex(Mutex) liefert bei mir auch immer nur NULL zurück und daher weiß ich leider nicht wie ich beides "vernüpftig" nutzen kann.
kann mir da mal jemand ein bissl was erklären.
ich brauche dies nämlich für einige Critical Sektions, aber für 3 Arten.
1. Nur ein Thread darf den Codeteil nutzen, alle anderen warten.
2. Nur ein Thread darf den Code nutzen, alle anderen warten aber nicht sondern gehen mit einem Rückgabewert weiter so daß ich den codeteil überspringen kann.
3. Alle Threads dürfen den Codeteil gleichzeitig nutzen, außer wenn einer dies nicht zuläßt, dieser wartet dann und verriegelt die anderen.
1. ist das einfach lockmutex
aber wie bekomme ich das andere hin? mit TryLockMutex(Mutex) klappt es nicht korrekt soweit ich bisher getestet habe. probiere es seit gestern, aber mache jetzt gleich mal weiter, vielleicht komme ich ja noch drauf.
bin also für Tips dankbar.
Gruß
Toshy
[/edit]
Hi,
wie soll den TryLockMutex(Mutex) genau funktionieren, habe das wohl nicht ganz verstanden und wie soll sich darauf dann LockMutex(Mutex) verhalten.
TryLockMutex(Mutex) soll doch wenn vorhanden den mutex "verriegeln".
Das tut es zwar wohl auch, aber es liefert IMMER nur NULL zurück, das sollte denke ich nicht sein, oder? "otherwise" steht da doch.
Die Funktion TryLockMutex(Mutex) an sich ist sehr sinnvoll, vor allem in kombination mit LockMutex(Mutex), aber damit funktioniert es nicht so richtig bzw. sinnvoll. zwar verriegelt TryLockMutex(Mutex) den codeteil dann für "LockMutex(Mutex)", aber umgekehrt (leider) nicht. das TryLockMutex(Mutex) verriegelt kann ja nur sinnvoll sein, wenn "lockmutex" nicht gleichzeitig mit einem TryLockMutex(Mutex) laufen darf. aber das passiert ja doch, denn wenn lockmutex verriegelt gilt dies leider nicht für TryLockMutex(Mutex).
TryLockMutex(Mutex) liefert bei mir auch immer nur NULL zurück und daher weiß ich leider nicht wie ich beides "vernüpftig" nutzen kann.
kann mir da mal jemand ein bissl was erklären.
ich brauche dies nämlich für einige Critical Sektions, aber für 3 Arten.
1. Nur ein Thread darf den Codeteil nutzen, alle anderen warten.
2. Nur ein Thread darf den Code nutzen, alle anderen warten aber nicht sondern gehen mit einem Rückgabewert weiter so daß ich den codeteil überspringen kann.
3. Alle Threads dürfen den Codeteil gleichzeitig nutzen, außer wenn einer dies nicht zuläßt, dieser wartet dann und verriegelt die anderen.
1. ist das einfach lockmutex
aber wie bekomme ich das andere hin? mit TryLockMutex(Mutex) klappt es nicht korrekt soweit ich bisher getestet habe. probiere es seit gestern, aber mache jetzt gleich mal weiter, vielleicht komme ich ja noch drauf.
bin also für Tips dankbar.
Gruß
Toshy
Zuletzt geändert von Toshy am 06.02.2006 22:58, insgesamt 1-mal geändert.
- remi_meier
- Beiträge: 1078
- Registriert: 29.08.2004 20:11
- Wohnort: Schweiz
Kleiner Beispielcode:
TryLockMutex() wird z. B. so verwendet (ausm Kopf):
Code: Alles auswählen
enableexplicit
Global Dim names.s(3)
Global NewList queue.s()
Global counter.l, mutex.l
names(0) = "peter"
names(1) = "hans"
names(2) = "franz"
names(3) = "juuli"
mutex = CreateMutex()
Procedure thread(index.l)
Protected name.s, z.l
name = names(index)
z = 0
Repeat
LockMutex(mutex)
counter + 1
AddElement(queue())
queue() = name
UnlockMutex(mutex)
Delay(Random(500) + 200)
z + 1
Until z = 20
EndProcedure
Define.l t
t = CreateThread(@thread(), 0)
t = CreateThread(@thread(), 1)
t = CreateThread(@thread(), 2)
t = CreateThread(@thread(), 3)
Repeat
LockMutex(mutex)
ForEach queue()
Debug queue()
DeleteElement(queue())
Next
UnlockMutex(mutex)
Delay(50)
Until counter = 80
FreeMutex(mutex)
Code: Alles auswählen
; im Thread:
changed = #false
repeat
If TryLockMutex(mutex)
; änder das was du ändern willst
changed = #true
else
; mach was solange die ressource gebraucht wird -> Wird nicht unter-
; brochen mit LockMutex()
EndIf
until changed
- remi_meier
- Beiträge: 1078
- Registriert: 29.08.2004 20:11
- Wohnort: Schweiz
Hatte grad etwas Zeit:
greetz
Remi
edit: nach Freak ausgebessert!
Code: Alles auswählen
Global mutex.l
mutex = CreateMutex()
Procedure test(dummy.l)
Delay(500)
Protected changed.l
changed = #False
Repeat
If TryLockMutex(mutex)
Debug "Endlich durchgekommen!"
changed = #True
UnLockMutex(mutex)
Else
Delay(100)
Debug "Mann! Du blockst mich"
EndIf
Until changed
EndProcedure
t = CreateThread(@test(), 5)
LockMutex(mutex)
Delay(1000)
; eine Sekunde lang blocken
UnlockMutex(mutex)
WaitThread(t)
FreeMutex(mutex)
Debug "Ende!"
Remi
edit: nach Freak ausgebessert!
Zuletzt geändert von remi_meier am 06.02.2006 17:07, insgesamt 1-mal geändert.
LockMutex() wartet bis der Mutex frei ist.
TryLockMutex() wartet nicht, sondern gibt 0 zurück wenn der Mutex nicht frei war.
remi_meier:
Nach einem erfolgreichen TryLockMutex() muss auch ein UnlockMutex() stehen,
sonst bleibt er immer im "locked" status. (ist in dem Beispiel egal, sonst aber ungemein wichtig.)
TryLockMutex() wartet nicht, sondern gibt 0 zurück wenn der Mutex nicht frei war.
remi_meier:
Nach einem erfolgreichen TryLockMutex() muss auch ein UnlockMutex() stehen,
sonst bleibt er immer im "locked" status. (ist in dem Beispiel egal, sonst aber ungemein wichtig.)
- remi_meier
- Beiträge: 1078
- Registriert: 29.08.2004 20:11
- Wohnort: Schweiz
-
- Beiträge: 713
- Registriert: 22.03.2005 00:29
- Computerausstattung: Computer und Strom vorhanden
- Wohnort: LK Wolfenbüttel
Ich hatte gestern noch was getest und zwar, war ich beim testen sehr verwirrt und sehe jetzt klarer. Leider scheint das NICHT zu stimmen was du schreibst. Ich dachte auch das dies so sein soll, aber es ist so das Try.. auch STARTET wenn der code vom normalen LOCK ausgeführt wird. Der unterschied ist, es wird beim aufruf vom Try der normale "lock-thread-code" GESTOPPT. das ist ja an sich toll, hilft aber in den meißten fällen nicht. zwar kann so nicht doppelt etwas beschrieben werden, aber stellt man sich für, thread A beschreibt eine einen listeneintrag (mehrere felder), er wird gestoppt und dann wird dieser eintrag gelöscht. was dann? also es ist nicht so, das der "Try-Code" erst dann ausgeführt wird, wenn der normale code AM ANFANG gestoppt wurde, oder wenn er abgearbeitet wird, sondern SOFORT (mit stoppen des anderen threads).TryLockMutex() wird z. B. so verwendet (ausm Kopf):
Code:
; im Thread:
changed = #false
repeat
If TryLockMutex(mutex)
; änder das was du ändern willst
changed = #true
else
; mach was solange die ressource gebraucht wird -> Wird nicht unter-
; brochen mit LockMutex()
EndIf
until changed
Das kann so Katastrophen führen und die Funktion wohl in den meißten Fällen nicht zu bebrauchen. Auf jedenfall bei mir in keinem einzigen Fall.
auf jedenfall sah es bisher so aus.
Ist natürlich schwer sowas zu testen
Aber auf Grund eurer Infos teste ich mal, denn ich kann mich ja total irren.
......
so, ne ganze Testzeit später.
....
ich könnte jetzt den Text oben weglöschen, aber so sieht man wie ich es gedacht hatte. Das lag wohl am schlechten Englisch meinerseits wie aber auch an meiner eigenen CSsektun die halt etwas anders arbeitet.
Ich werde zwar jetzt erst recht testen müssen, aber schön zu wissen wie es gemeint ist.
Daher zum voräufigen Abschluß also noch wichtige Punkte:
1. Ich habe mich also total geirrt in der Auffassung der Funktion Try...
2. Großes Danke an euch

Gruß
Toshy
-
- Beiträge: 713
- Registriert: 22.03.2005 00:29
- Computerausstattung: Computer und Strom vorhanden
- Wohnort: LK Wolfenbüttel
@remi_meier
Also da habe ich mich doch zu früh gefreut. von euer erklärung und dem beispiel klang alles super, aber es klappt nicht.
beim beispiel kommt minuten lang (auch ganz zu anfang) nur
"Mann! Du blockst mich"
Trylock ist IMMER null.
auch mal nur zum test
m = CreateMutex()
Debug m
Ergebnis = TryLockMutex(m)
Debug Ergebnis
ist immer null bei mir.
[edit]ich meine deinen Zweiten code, den ersten noch nicht getest.
aber Try gibt bisher bei mir halt IMMER NULL zurück.
Bin ich jetzt blöd oder was?
Also da habe ich mich doch zu früh gefreut. von euer erklärung und dem beispiel klang alles super, aber es klappt nicht.
beim beispiel kommt minuten lang (auch ganz zu anfang) nur
"Mann! Du blockst mich"
Trylock ist IMMER null.
auch mal nur zum test
m = CreateMutex()
Debug m
Ergebnis = TryLockMutex(m)
Debug Ergebnis
ist immer null bei mir.
[edit]ich meine deinen Zweiten code, den ersten noch nicht getest.
aber Try gibt bisher bei mir halt IMMER NULL zurück.
Bin ich jetzt blöd oder was?
-
- Beiträge: 713
- Registriert: 22.03.2005 00:29
- Computerausstattung: Computer und Strom vorhanden
- Wohnort: LK Wolfenbüttel
Hallo.
Ich bin mir sicher, das ist ein Bug.
Ich dachte ich bin blöd, aber dem ist wohl doch nicht so.
Ich habe mal zum testen, weil mir hier einiges sehr komisch war diesen Code zur EXE kompiliert und auf meinem Windows XP Rechner laufen lausen. Und oh wunder, der Code läuft, Trylockmutex() funktioniert.
Aber auf meinem Windows 98 Rechner geht es NICHT (kein SE).
Bei Windows 98 funktioniert trylockmutex nicht.
Wie kann das denn sein?
Gruß
Thorsten
[edit]
ach ja, ich weiß natürlich nicht, ob es am unterschiedlichen betriebssytem liegt oder das der Rechner auf dem es geht einen AMD 2400XP besitzt und auf dem es nicht geht ein AMD 1800XP CPU ist.
Ich bin mir sicher, das ist ein Bug.
Ich dachte ich bin blöd, aber dem ist wohl doch nicht so.
Code: Alles auswählen
OpenConsole()
Global mutex.l
mutex = CreateMutex()
Procedure test(dummy.l)
Delay(500)
Protected changed.l
changed = #False
Repeat
If TryLockMutex(mutex)
PrintN( "Endlich durchgekommen!" )
changed = #True
UnlockMutex(mutex)
Else
Delay(100)
PrintN( "Mann! Du blockst mich" )
EndIf
Until changed
EndProcedure
t = CreateThread(@test(), 5)
LockMutex(mutex)
Delay(1000)
; eine Sekunde lang blocken
UnlockMutex(mutex)
WaitThread(t)
FreeMutex(mutex)
Delay(15000)
Debug "Ende!"
CloseConsole()
Aber auf meinem Windows 98 Rechner geht es NICHT (kein SE).
Bei Windows 98 funktioniert trylockmutex nicht.
Wie kann das denn sein?
Gruß
Thorsten
[edit]
ach ja, ich weiß natürlich nicht, ob es am unterschiedlichen betriebssytem liegt oder das der Rechner auf dem es geht einen AMD 2400XP besitzt und auf dem es nicht geht ein AMD 1800XP CPU ist.