Mutex nutzlos?

Für allgemeine Fragen zur Programmierung mit PureBasic.
Lambda
Beiträge: 526
Registriert: 16.06.2011 14:38

Re: Mutex nutzlos?

Beitrag 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?
Benutzeravatar
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

Re: Mutex nutzlos?

Beitrag 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.
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.
Bild
Lambda
Beiträge: 526
Registriert: 16.06.2011 14:38

Re: Mutex nutzlos?

Beitrag 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)
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7039
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Mutex nutzlos?

Beitrag 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.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Lambda
Beiträge: 526
Registriert: 16.06.2011 14:38

Re: Mutex nutzlos?

Beitrag 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.
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7039
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Mutex nutzlos?

Beitrag 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!
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Lambda
Beiträge: 526
Registriert: 16.06.2011 14:38

Re: Mutex nutzlos?

Beitrag 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?
Benutzeravatar
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

Re: Mutex nutzlos?

Beitrag 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.
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.
Bild
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7039
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Mutex nutzlos?

Beitrag 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.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Lambda
Beiträge: 526
Registriert: 16.06.2011 14:38

Re: Mutex nutzlos?

Beitrag 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.
Zuletzt geändert von Lambda am 10.08.2012 18:01, insgesamt 1-mal geändert.
Antworten