Threads: Zugriff auf strukturierten Speicher

Für allgemeine Fragen zur Programmierung mit PureBasic.
Benutzeravatar
Kurzer
Beiträge: 1617
Registriert: 25.04.2006 17:29
Wohnort: Nähe Hamburg

Threads: Zugriff auf strukturierten Speicher

Beitrag von Kurzer »

Hallo,

ich habe eine Frage bzgl. des Zugriffs auf ein und die selbe Instanz eines Strukturspeichers aus mehreren Threads heraus. In meinem Fall geht es um ein Customgadget (Kurvendiagramm-Anzeige), welches unter anderem diverse Setter-Prozeduren anbietet. Das Gadget hält seine Daten in einer Struktur im Speicher.

Es erfolgen dort Zugriffe nach folgendem Schema:

Code: Alles auswählen

With *GraphGadget
	\stBuffer[iBufferNumber]\iBufferShowGrid = iBufferShowGrid
	\stBuffer[iBufferNumber]\iBufferGraphGridSize = iBufferGraphGridSize
	\stBuffer[iBufferNumber]\iBufferGraphGridColour = iBufferGraphGridColour
	; ... usw.
EndWith
Nun rufe ich diese Setter-Prozeduren (SetBufferAddress(), SetBufferOffset() usw.) periodisch aus einem Thread heraus auf und habe gleichzeitig ein paar Testbuttons im Main() laufen, die diese Prozeduren ebenfalls aufrufen.

Ich habe das Testprogramm ohne die Compilerenstellung "Threadsave" laufen und beim Herumklicken mit den Buttons sporadische Speicherzugriffsfehler festgestellt. Offenbar immer dann, wenn Thread und Main() gleichzeitig auf die Struktur zugreifen.

Nun habe ich alle Prozeduren, die auf den Strukturspeicher des Gadgets zugreifen wie folgt abgesichert (ich wollte dafür nicht extra einen Mutex() bemühen):

Code: Alles auswählen

; Wait until the Gadget is unlocked
While *GraphGadget\iGadgetLocked = #True : Delay(1) : Wend
*GraphGadget\iGadgetLocked = #True
With *GraphGadget
	\stBuffer[iBufferNumber]\iBufferShowGrid = iBufferShowGrid
	\stBuffer[iBufferNumber]\iBufferGraphGridSize = iBufferGraphGridSize
	\stBuffer[iBufferNumber]\iBufferGraphGridColour = iBufferGraphGridColour
	; ... usw.
EndWith		
*GraphGadget\iGadgetLocked = #False
Bisher habe ich keine Speicherfehler mehr festgestellt und gehe davon aus, dass meine Vermutung mit der Kollision beim Zugriff auf den Strukturspeicher richtig war.

Aber ich frage lieber nochmal nach: Ist es richtig, dass eine Exe abschmieren kann, wenn mehrere Threads (oder ein Thread und main() ) gleichzeitig auf einen strukturierten Speicherbreich zugreifen? Bisher dachte ich, dass dies nur bei Verwendung von Strings Probleme bereitet.

Und kann man das so lösen wie ich es getan habe (*GraphGadget\iGadgetLocked = #True)?

Nachtrag: Kann es sein, dass ein Mutex quasi genau das macht was ich oben zu Fuß mache? Ich habe keine Ahnung wie ein Mutex intern realisiert wird.

Nachtrag 2: Ich habe die Prozeduren jetzt mit einem Mutex gelocked. Auch hier keine Speicherfehler mehr und obendrein weniger Codezeilen. Ich gehe mal davon aus, das ein Mutex intern nicht viel mehr Ressourcen verbraucht als meine vorherige "zu Fuß" Lösung.

Code: Alles auswählen

; Wait until the Gadget is unlocked
LockMutex(*GraphGadget\iGadgetMutex)

;... some code		
		
UnlockMutex(*GraphGadget\iGadgetMutex)
"Never run a changing system!" | "Unterhalten sich zwei Alleinunterhalter... Paradox, oder?"
PB 6.02 x64, OS: Win 7 Pro x64 & Win 11 x64, Desktopscaling: 125%, CPU: I7 6500, RAM: 16 GB, GPU: Intel Graphics HD 520
Useralter in 2024: 56 Jahre.
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: Threads: Zugriff auf strukturierten Speicher

Beitrag von ts-soft »

Wenn ein Thread auf den Speicher zugreift, wird er für weitere Threads gesperrt, was leider nicht ausreicht, weil wenn 2 oder mehrere Threads auf den Speicher zugreifen (quasi "zeitgleich"), ist es zu spät zum sperren weiterer Threads, weil dann ist es schon passiert.

Es ist also die CompilerOption Threadsafe (vor allem für Strings) sowie ein Mutex erforderlich! Alles andere führt früher oder später zu Fehlern. Es kommt auch nicht drauf an, wie wahrscheinlich so ein Fehler ist, sondern er ist grundsätzlich auszuschließen. Murphy läßt grüßen :mrgreen:
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
Kurzer
Beiträge: 1617
Registriert: 25.04.2006 17:29
Wohnort: Nähe Hamburg

Re: Threads: Zugriff auf strukturierten Speicher

Beitrag von Kurzer »

Alles klar, dann bin ich ja mit meiner letzten Version (mit Mutex) schon auf dem richtigen Weg gewesen. Fehlt dann nur noch die Option "Threadsafe" in den Compilereinstellungen. :allright:
"Never run a changing system!" | "Unterhalten sich zwei Alleinunterhalter... Paradox, oder?"
PB 6.02 x64, OS: Win 7 Pro x64 & Win 11 x64, Desktopscaling: 125%, CPU: I7 6500, RAM: 16 GB, GPU: Intel Graphics HD 520
Useralter in 2024: 56 Jahre.
Antworten