Seite 2 von 4

Re: Mutex nutzlos?

Verfasst: 10.08.2012 17:09
von Lambda
Okay, bereits getestet, was allerdings Probleme aufwirft.

Und zwar ruckeln. Deswegen wollte ich eine echtzeit Snychonisation. ^^ Ich muss mit DLL Befehlen Werte von Elementen permanent ändern können ohne zu warten bis die Liste fertig ist.

Ist so ein paraleller Zugriff mit Adressen vielleicht möglich?

Re: Mutex nutzlos?

Verfasst: 10.08.2012 17:18
von ts-soft
cOoki3druqs hat geschrieben:Ist so ein paraleller Zugriff mit Adressen vielleicht möglich?
Nein, es darf nur ein Thread in einem Speicher schreiben.
Du kannst nur versuchen die Zeit wo der Mutex gelocked ist, zu minimieren, indem Du alle vorarbeiten ausserhalb des Lockes erledigst.

Re: Mutex nutzlos?

Verfasst: 10.08.2012 17:27
von Lambda
Naja, der Thread ändert die Daten nie, er liest nur. Das Problem ist, er rendert permanent Einzelbilder - wird er gesperrt führt das eben zum ruckeln. (also selbst durch TryLockMutex)

Re: Mutex nutzlos?

Verfasst: 10.08.2012 17:29
von STARGÅTE
Hier mal ein Beispiel:

So könnte deine Schleifen aussehen

Code: Alles auswählen

LockMutex(Mutex)
ForEach Element()
	*Element.Struktur = Element()
	UnlockMutex(Mutex)
	
	; Hier irgendwas mit *Element machen, und auch nut mit *Element zugreifen
	
	LockMutex()
	ChangeCurrentElement(Element(), *Element)
Next
UnlockMutex(Mutex)
So wird während der Berechnungen am Element kein Zugriff gesperrt.
Die Liste wird aber durch das ChangeCurrentElement() trotzdem durchgearbeitet.

Wenn du von außen ein Element hinzufügst, dann bitte:

Code: Alles auswählen

LockMutex(Mutex)
AddElement(Element())
Element()\X = 12
;..
UnlockMutex(Mutex)
Beachte aber, dass das Element dann "irgend wo" in der Liste hinzugefügt wird (nicht am Ende).
Je nachdem wo die Foreach-Schleifen gerade sind.

Re: Mutex nutzlos?

Verfasst: 10.08.2012 17:39
von Lambda
Ich denk mal der größte Aussetzer wird durch den Render-Thread verursacht.

Wenn er das Mutex sperrt rendert er alle Elemente, wenn aber von drausen der Behfel kommt ein Bild z.B zu rotieren, wartet der Befehl erstmal bis das Mutex frei ist. Neben den granzen Zeichenoperationen kommt noch ein Delay und Ereignisverarbeitung, was also dazu führt, dass selbst wenn es jetzt neu gezeichnet werden würde der DLL Befehl es schonwieder im Besitz hat.

Beide Seiten laufen also permanent, dürfen sich aber gegenseitig nicht ausschließen.

Re: Mutex nutzlos?

Verfasst: 10.08.2012 17:41
von STARGÅTE
Sry für Doppelpost:

Hier ein ausführbares Beispiel:
Der Thread oben ließt ununterbrochen die Liste (mit seinen kleinen Pausen).
Per Button kannst du aber zu jeder Zeit Elemente hinzufügen ohne die Liste zu stören.
(Thread-Sicher einschalten!)

Code: Alles auswählen

Global Mutex = CreateMutex()

Structure Element
	String.s
EndStructure

Global NewList Element.Element()

Procedure Lesen(Void)
	Protected *Element.Element
	Repeat
		Delay(1000)
		Debug "Elemente: "
		LockMutex(Mutex)
		ForEach Element()
			*Element = Element()
			UnlockMutex(Mutex)
			Delay(100)
			Debug "  "+*Element\String
			LockMutex(Mutex)
			ChangeCurrentElement(Element(), *Element)
		Next
		UnlockMutex(Mutex)
	ForEver
EndProcedure

CreateThread(@Lesen(), #Null)

Enumeration
	#Window
	#Gadget
EndEnumeration


OpenWindow(#Window, 0, 0, 220, 40, "WindowTitle", #PB_Window_MinimizeGadget|#PB_Window_ScreenCentered)
	ButtonGadget(#Gadget, 10, 10, 200, 20, "Add Element")

Define Nummer.i, *Element.Element

Repeat
	
	Select WaitWindowEvent()
			
		Case #PB_Event_CloseWindow
			End
			
		Case #PB_Event_Gadget
			Select EventGadget()
				Case #Gadget
					LockMutex(Mutex)
					*Element = AddElement(Element())
					UnlockMutex(Mutex)
					*Element\String = "Element "+Str(Nummer)
					Nummer + 1
					
			EndSelect
			
	EndSelect
	
ForEver
WICHTIG: Beachte aber hier, dass wenn unten gerade in das neue Element geschrieben wird, und der obere Thread schon ließt, die Daten unvollständig sind, was ggf zm Fehler/Absturz führen kann.
Dort musst du dann also ggf. den Mutex-Sperrbereich ausweiten!

Re: Mutex nutzlos?

Verfasst: 10.08.2012 17:45
von Lambda
Damit ich das Ziel deiner Lösung versteh:

Du entsperrst also nach jedem Sprung in der ForEach Schleife damit die Sperrzeit verringert wird? Kann es so noch zu Kollisionen führen oder minimiert es sie nur deutlich?

Re: Mutex nutzlos?

Verfasst: 10.08.2012 17:48
von ts-soft
Wichtig ist auch, von der Logik her muss ein gleichzeitiger Zugriff von mehreren Threads ausgeschlossen sein, es nützt nichts,
eine Routine 1000x zu testen und dann anzunehmen, es gab keine Fehler, es ist alles okay.

Murphy wird Dich früher oder später eines besseren belehren :wink:

// edit: seine Lösung minimiert die Wahrscheinlichkeit, was ich als unzureichend ansehe.

Re: Mutex nutzlos?

Verfasst: 10.08.2012 17:51
von STARGÅTE
Es gibt so keine Kollision mehr zwischen dem FoEach und einem AddElement.
Die Kollision in den Elementen selber bleibt aber bestehen!

Um nicht weiter im Dunklen zu stochern wäre es das einfachste, wenn du eine Vereinfache Version deines Codes hier postest, damit ihr in anpassen können.

Re: Mutex nutzlos?

Verfasst: 10.08.2012 17:54
von Lambda
Betrifft also ein geteilter Speichernur den Zugriff? Eigentlich greifen selbst 100 Threads nie gleichzeitig auf ein Speicher zu, da jeder Schritt für Schritt abgearbeitet wird, oder nicht?

Für meine "top-level" Liste nutz ich ein Array, wodurch ich das sperren/entsperren vorerst umgehn konnte. Muss allerdings zugeben das nach einigen Minuten Laufzeit es doch mal unvorhergesehn zum Absturz führte.


AAAARHHH.. entschuldigt! Habe mein eigenes System vergessen. Dieses "ruckeln" ist die Framerate, die ich eben aus Testzwecken nichtmehr geändert hatte.