Thread erstellt und dennoch ungültiger Speicherzugriff

Anfängerfragen zum Programmieren mit PureBasic.
Paddy1988
Beiträge: 19
Registriert: 28.12.2015 15:31

Thread erstellt und dennoch ungültiger Speicherzugriff

Beitrag von Paddy1988 »

Hallo ihr :)

ich habe mal wieder ein Problem mit Threads, eigentlich hat es bei meinem letzten Programm gut funktioniert.
Jedoch bei diesem Programm bekomme ich eine Fehlermeldung 'ungültiger Speicherzugriff, Lesefehler an der Adresse 149917696', jedoch sollte doch dieses Problem mit Threads eigentlich nicht auftreten oder?

Bei dem Programm werden Dateien eingelesen, daraus Informationen gezogen und mehrere Datenbankabfragen generiert. Diese datenbankabfragen werden nacheinander ausgeführt und die Ergebnisse jeder Abfrage direkt in eine CSV-Datei geschrieben, die Datenbankabfragen dauern ziemlich lange wobei sich das Programmfenster aufhängt (keine Rückmeldung). Das Programm läuft jedoch weiter und sobald es abgeschlossen ist, ist es auch wieder bedienbar.

An den Thread sollen insgesamt 4 Parameter übergeben werden.

zum einen die SQL-Abfrage, der Dateipfad wo zu lesende Datei liegt, der Name der Datei, und das Zielverzeichnis der zu erstellenden Datei.

Code: Alles auswählen

Declare Thread(*tData.ThreadData)

Structure ThreadData
  thread_sql_abfrage.s
  thread_dateipfad.s
  thread_dateiname.s
  thread_ziel_verzeichnis.s
EndStructure

Code: Alles auswählen

Procedure sql_scripte_erstellen(dateipfad$, dateiname$, ziel_verzeichnis$)
........
  sql_abfrage$="Select * From ....."
  Define tData.ThreadData
  tData\thread_sql_abfrage=sql_abfrage$
  tData\thread_dateipfad=dateipfad$
  tData\thread_dateiname=dateiname$
  tData\thread_ziel_verzeichnis=ziel_verzeichnis$
  Thread = CreateThread(@Thread(), tData)
.......
EndProcedure

Code: Alles auswählen

Procedure Thread(*tData.ThreadData)
  sql_abfrage_ausfuehren(*tData\thread_sql_abfrage,*tData\thread_dateipfad, *tData\thread_dateiname, *tData\thread_ziel_verzeichnis)
EndProcedure

Code: Alles auswählen

Procedure sql_abfrage_ausfuehren(sql_abfrage$, dateipfad$, dateiname$, ziel_verzeichnis$)
........
........
EndProcedure
Ich weiß jetzt nicht ob ihr etwas damit anfangen könnt, jedenfalls möchte ich 4 String Parameter an einen Thread übergeben und die Abarbeitung meiner Datenbankabfrage sowie das erstellen der Dateien soll ablaufen ohne dass sich mein Programm aufhängt.

Habt ihr eine Idee, was ich machen könnte um den Speicherfehler nicht zu bekommen, ich habe noch etwas von CreateMutex() gelesen, habe aber kein Plan wie man das verwenden soll.
Für jede Hilfe wäre ich sehr dankbar. :allright:
Benutzeravatar
man-in-black
Beiträge: 362
Registriert: 21.08.2006 17:39

Re: Thread erstellt und dennoch ungültiger Speicherzugriff

Beitrag von man-in-black »

Hi,

du fütterst den Thread nur mit Pointern zu einer strukturierten Variable und nicht mit einer neuen Instanz.
Sobald " sql_scripte_erstellen" den Thread erstellt hat, wird die Procedure beendet und alle lokalen Variablen freigegeben.
Dein Thread besitzt damit nurnoch Pointer auf nicht reservierten Speicher. Ich würde den Speicher folglich über AllocateMemory
reservieren und vom Thread selbst freigeben lassen. (Hoffe, ich erzähle jetzt keinen Käse und PB arbeitet so, wie beschrieben)

Code: Alles auswählen

Procedure sql_scripte_erstellen(dateipfad$, dateiname$, ziel_verzeichnis$)
........
  sql_abfrage$="Select * From ....."
  Define tData.ThreadData
  tData\thread_sql_abfrage=sql_abfrage$
  tData\thread_dateipfad=dateipfad$
  tData\thread_dateiname=dateiname$
  tData\thread_ziel_verzeichnis=ziel_verzeichnis$
  Thread = CreateThread(@Thread(),tData)                      tData <=> Pointer
.......
EndProcedure
MFG
MIB
(hab alles, kann alles, weiß alles!!^^)

Bild
Paddy1988
Beiträge: 19
Registriert: 28.12.2015 15:31

Re: Thread erstellt und dennoch ungültiger Speicherzugriff

Beitrag von Paddy1988 »

Erst einmal danke für die Hilfe, aber wohin soll das mit dem AllocateMemory?
So wie ich es gemacht habe klappt es nicht /:->

Code: Alles auswählen

Procedure sql_scripte_erstellen(dateipfad$, dateiname$, ziel_verzeichnis$)
........
  sql_abfrage$="Select * From ....."
  Define tData.ThreadData
  tData\thread_sql_abfrage=sql_abfrage$
  tData\thread_dateipfad=dateipfad$
  tData\thread_dateiname=dateiname$
  tData\thread_ziel_verzeichnis=ziel_verzeichnis$
  speicher_thread=AllocateMemory(SizeOf(tData))
  Thread = CreateThread(@Thread(),tData)                      tData <=> Pointer
.......
EndProcedure

Code: Alles auswählen

Procedure Thread(*tData.ThreadData)
  sql_abfrage_ausfuehren(*tData\thread_sql_abfrage,*tData\thread_dateipfad, *tData\thread_dateiname, *tData\thread_ziel_verzeichnis)
  FreeMemory(speicher_thread)
EndProcedure
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: Thread erstellt und dennoch ungültiger Speicherzugriff

Beitrag von NicTheQuick »

So:

Code: Alles auswählen

Procedure sql_scripte_erstellen(dateipfad$, dateiname$, ziel_verzeichnis$)
........
  sql_abfrage$="Select * From ....."
  Define *tData.ThreadData = AllocateStructure(ThreadData)
  *tData\thread_sql_abfrage=sql_abfrage$
  *tData\thread_dateipfad=dateipfad$
  *tData\thread_dateiname=dateiname$
  *tData\thread_ziel_verzeichnis=ziel_verzeichnis$
  Thread = CreateThread(@Thread(), *tData)
.......
EndProcedure

Procedure Thread(*tData.ThreadData)
  sql_abfrage_ausfuehren(*tData\thread_sql_abfrage,*tData\thread_dateipfad, *tData\thread_dateiname, *tData\thread_ziel_verzeichnis)
  FreeMemory(*tData)
EndProcedure
Paddy1988
Beiträge: 19
Registriert: 28.12.2015 15:31

Re: Thread erstellt und dennoch ungültiger Speicherzugriff

Beitrag von Paddy1988 »

Ok danke, soweit klappt das jetzt, aber nur bei einer Datei einlesen.

Wenn ich mehrere Dateien einlese, fängt er an eine neue Datei einzulesen obwohl er noch nicht die Datenbankabfrage der ersten Datei ausgewertet hat, für mich total unlogisch da ich mit 'While NextDirectoryEntry(verzeichnishandle)' arbeite und so jede datei nacheinander öffne und abarbeite.
Jetzt sieht es so aus als öffnet er erst einmal alle Dateien liest Informationen aber die Datenbankverbindung macht er erst nachdem die letzte Datei eingelesen wurde.
Das ergibt keinen Sinn und widerspricht meinem Programmablauf.

Könnte das jetzt mit diesem CreateMutex() zu tun haben?
:roll:
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: Thread erstellt und dennoch ungültiger Speicherzugriff

Beitrag von NicTheQuick »

Das wissen wir nicht, da wir von dir nie einen lauffähigen Code bekommen haben. ;) Das würde wahrscheinlich viel Fragerei ersparen. :)
Paddy1988
Beiträge: 19
Registriert: 28.12.2015 15:31

Re: Thread erstellt und dennoch ungültiger Speicherzugriff

Beitrag von Paddy1988 »

Paddy1988 hat geschrieben:Ok danke, soweit klappt das jetzt, aber nur bei einer Datei einlesen.

Wenn ich mehrere Dateien einlese, fängt er an eine neue Datei einzulesen obwohl er noch nicht die Datenbankabfrage der ersten Datei ausgewertet hat, für mich total unlogisch da ich mit 'While NextDirectoryEntry(verzeichnishandle)' arbeite und so jede datei nacheinander öffne und abarbeite.
Jetzt sieht es so aus als öffnet er erst einmal alle Dateien liest Informationen aber die Datenbankverbindung macht er erst nachdem die letzte Datei eingelesen wurde.
Das ergibt keinen Sinn und widerspricht meinem Programmablauf.

Könnte das jetzt mit diesem CreateMutex() zu tun haben?
:roll:

Außerdem kommt der Fehler das das angegebene '*MemoryID' ungültig sei, bei FreeMemory(*tData)
Paddy1988
Beiträge: 19
Registriert: 28.12.2015 15:31

Re: Thread erstellt und dennoch ungültiger Speicherzugriff

Beitrag von Paddy1988 »

Paddy1988 hat geschrieben:
Paddy1988 hat geschrieben:Ok danke, soweit klappt das jetzt, aber nur bei einer Datei einlesen.

Wenn ich mehrere Dateien einlese, fängt er an eine neue Datei einzulesen obwohl er noch nicht die Datenbankabfrage der ersten Datei ausgewertet hat, für mich total unlogisch da ich mit 'While NextDirectoryEntry(verzeichnishandle)' arbeite und so jede datei nacheinander öffne und abarbeite.
Jetzt sieht es so aus als öffnet er erst einmal alle Dateien liest Informationen aber die Datenbankverbindung macht er erst nachdem die letzte Datei eingelesen wurde.
Das ergibt keinen Sinn und widerspricht meinem Programmablauf.

Könnte das jetzt mit diesem CreateMutex() zu tun haben?
:roll:

Außerdem kommt der Fehler das das angegebene '*MemoryID' ungültig sei, bei FreeMemory(*tData)
Ich würde gerne den lauffähigen Code posten aber ihr habt ja keine Verbindung zu meiner Datenbank :roll: , daher wird es schwer.
Benutzeravatar
Bisonte
Beiträge: 2468
Registriert: 01.04.2007 20:18

Re: Thread erstellt und dennoch ungültiger Speicherzugriff

Beitrag von Bisonte »

Die Datenbank ist unwichtig... es geht um deinen Programmablauf.

Und nebenbei... man kann seine Postings editieren.
PureBasic 6.21 (Windows x86/x64) | Windows11 Pro x64 | AsRock B850 Steel Legend Wifi | R7 9800x3D | 64GB RAM | GeForce RTX 5080 | ThermaltakeView 270 TG ARGB | build by vannicom​​
Benutzeravatar
man-in-black
Beiträge: 362
Registriert: 21.08.2006 17:39

Re: Thread erstellt und dennoch ungültiger Speicherzugriff

Beitrag von man-in-black »

Wenn ich mehrere Dateien einlese, fängt er an eine neue Datei einzulesen obwohl er noch nicht die Datenbankabfrage der ersten Datei ausgewertet hat, für mich total unlogisch da ich mit 'While NextDirectoryEntry(verzeichnishandle)' arbeite und so jede datei nacheinander öffne und abarbeite.
Jetzt sieht es so aus als öffnet er erst einmal alle Dateien liest Informationen aber die Datenbankverbindung macht er erst nachdem die letzte Datei eingelesen wurde.
Das ergibt keinen Sinn und widerspricht meinem Programmablauf.
Schonmal dran gedacht, dass deine Threads nebenher laufen? Kann gut sein, dass deine Datenbankanfragen mehr Zeit in
Anspruch nehmen als das Auslesen deines Verzeichnisses. Ergo kommt deine Auswertung erst zum Schluss an.
Außerdem kommt der Fehler das das angegebene '*MemoryID' ungültig sei, bei FreeMemory(*tData)
Wie oft nutzt du "tData" innerhalb deiner Procedure? Wenn du den Speicher überschreibst oder mehrere Anfragen
mit dem gleichen Speicher nutzt, wird dir der erste Thread den Speicher natürlich freigeben und Folgende gucken ins Leere.

MFG
MIB
(hab alles, kann alles, weiß alles!!^^)

Bild
Antworten