thread problem...

Anfängerfragen zum Programmieren mit PureBasic.
teamO
Beiträge: 56
Registriert: 01.03.2010 20:01

thread problem...

Beitrag von teamO »

Hi,

Erst mal im Voraus: Ich ich hab schon etwas PB Erfahrung, aber Threads sind absolutes Neuland für mich.

das Problem: Ich bin grad dabei in einem Programm eine rechenintensive Prozedur in einen extra thread auszulagern. Die Prozedur ruft andere Prozeduren auf, die aber vom Hauptprogramm nicht aufgerufen werden. Außerdem greift der neue Thread auf globale Arrays und listen zu, auf die auch im Hauptprogramm zugegriffen wird.
Das problem ist, dass nun an den unmöglichsten Stellen invalid memory access fehler kommen. Beispielsweise bei "next" oder "endProcedure" :?
Auffallend ist auch, dass der read error immer bei den gleichen Adressen auftritt - selbst an einem anderen PC. :o
Ist das "normal"???
Und hat jemand ne idee an was das liegen könnte?

Grüße,
TeamO

PS: ich nutze PB 4.50
Benutzeravatar
Thorium
Beiträge: 1722
Registriert: 12.06.2005 11:15
Wohnort: Germany
Kontaktdaten:

Re: thread problem...

Beitrag von Thorium »

Hast du threadsave in den compileroptionen aktiviert?
Und hast du alle Zugriffe auf globale arrays ect. mit Mutexes geschützt?
Zu mir kommen behinderte Delphine um mit mir zu schwimmen.

Wir fordern mehr Aufmerksamkeit für umfallende Reissäcke! Bild
teamO
Beiträge: 56
Registriert: 01.03.2010 20:01

Re: thread problem...

Beitrag von teamO »

Thorium hat geschrieben:Hast du threadsave in den compileroptionen aktiviert?
ja
Thorium hat geschrieben:Und hast du alle Zugriffe auf globale arrays ect. mit Mutexes geschützt?
nee. Vielleicht eine blöde Frage, aber warum muss man das?
Benutzeravatar
Thorium
Beiträge: 1722
Registriert: 12.06.2005 11:15
Wohnort: Germany
Kontaktdaten:

Re: thread problem...

Beitrag von Thorium »

Das muss man nur, wenn mehrere threads auf die Arrays, Listen, etc. zugreifen, ansonsten kracht es, wenn beide gleichzeitig zugreifen. Threadsave ist nur für den internen stringmanager.
Zu mir kommen behinderte Delphine um mit mir zu schwimmen.

Wir fordern mehr Aufmerksamkeit für umfallende Reissäcke! Bild
teamO
Beiträge: 56
Registriert: 01.03.2010 20:01

Re: thread problem...

Beitrag von teamO »

das ging ja fast so schnell, wie im chat! :lol:

ich hab mir mal die Hilfe dazu angeschaut. Hab jetzt aber noch ein paar Fragen:
1. brauch ich das nur beim Schreib- oder auch beim Lesezugriff?
2. wie schnell ist das Sperren und entsperren?
geht das wenn man das 100k x pro sekunde macht?
also sollte man es besser so:

Code: Alles auswählen

for ....
  for ...
    lockmutex()
    zugriff
    unlockmutex()
  next
next
oder so:

Code: Alles auswählen

lockmutex()
for ....
  for ...
    zugriff
  next
next
unlockmutex()
machen?
Bei der 2. Variante wäre alles dann halt relativ lange gesperrt...
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: thread problem...

Beitrag von ts-soft »

in jedem Falle die zweite Variante, weil das Sperren dauert auch!
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
teamO
Beiträge: 56
Registriert: 01.03.2010 20:01

Re: thread problem...

Beitrag von teamO »

hm, das ist jetzt doch komplexer als ich dachte...
In meinem Beispiel hab ich verschachtelte Arrays und Listen. Dann wäre es wohl intelligent, wenn ich das mutex-Objekt nicht für die oberste Ebene verwende, sondern auf einer Zwischenebene, oder sogar auf der untersten verwende, oder?
Spricht etwas, außer dem höheren Speicherbedarf gegen tausende Mutex-Objekte?

Und wenn ich eine Variable nur les (also nicht schreib), beispielsweise als Parameter eine Prozedur übergeb, muss ich die dann dafür auch sperren? oder können zwei threads die gleiche Variable gleichzeitig lesen (bitte, bitte, bitte)?
Benutzeravatar
mk-soft
Beiträge: 3855
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: thread problem...

Beitrag von mk-soft »

Lesen von einfachen Variablen ist kein Problem. Beim Schreiben muss aber drauf geachtet werden welcher Thread was schreib.
Tausende von Mutex sind gar nicht erforderlich. Mit geschickter Aufteilung kommt man mit wenigen Mutex aus.

Bei Aufrufen von Proceduren sind die Parameter ByVal und somit eine Kopie dewr Variable. Ausgenommen natürlich wenn Parameter Pointer auf Strukturen sind oder Array, Listen.

Ganz so Kompliziert sind Threads gar nicht. Man muss nur daran denken das alles Asyncron läuft.
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
teamO
Beiträge: 56
Registriert: 01.03.2010 20:01

Re: thread problem...

Beitrag von teamO »

Ich bekomm den invalide memory access error nicht weg >_<

zum Test hab ich das ganze jetzt so aufgebaut:

Code: Alles auswählen

global all.i=createmutex()

procedure ...()
repeat
lockMutex(all)
;gesamte procedure
unlockMutex(all)
forever
endprocedure

createthread(@...(),0)

repeat
lockMutex(all)
;fenster und ganzer rest
unlockMutex(all)
for ever
und es gibt immernoch nach dem Bruchteil einer sekunde einen IAM error!
Nach meiner Logik kann das nicht sein. Oder hab ich einen Denkfehler?
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7031
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: thread problem...

Beitrag von STARGÅTE »

von der Art her schon mal die richtige Richtung.

Aber dem Thread solltest du n kleinen TimeOut geben Delay(0) oder 1, damit auch wirklich der Mutex richtig läuft und nicht n art dauersperre hat.

natürlich macht dein test jetzt kein IMA.

Aber du solltest folgendes beachten:
- Wenn man Listen durch geht (ForEach) oder so dann gibs in der liste immer n Aktuelles Element, hast du woanders auch so ein Forech welches parrallel läuft, dann "beeinflussen" sich die beiden Schleifen.
- Auch Thread-sicheres Exe macht die Exe nicht thread sicher ^^.
Wie ein anderer hier mal im Forum gezeigt hat kann man mit Threads in folgender Aussage ein WAHR erzeugen:

Code: Alles auswählen

If A And Not A
 Debug "WOW"
EndIf
"Lösung":

Code: Alles auswählen

Global A

Procedure LOL(Null=0)
 Repeat
  A = 1-A
 ForEver
EndProcedure

CreateThread(@LOL(), 0)

Repeat
 If A And Not A
  Debug "WOW"
  Break
 EndIf
ForEver
Auch bei Thread-sichere Exe !
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
Antworten