Thread Zugriffsverletzung

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
CFJH
Beiträge: 3
Registriert: Sa 12. Apr 2014, 19:02
OS, Lazarus, FPC: Suse (L 1.0.10 FPC 2.6.2)
CPU-Target: 64Bit
Wohnort: Erde
Kontaktdaten:

Thread Zugriffsverletzung

Beitrag von CFJH »

Hallo,
ich bin noch ganz frisch bei Lazarus, habe aber schon einige Delphi-Erfahrung.

Ich möchte ein bestehendes Programm erweitern, dabei soll in einem neu erstelltem Fenster per Thread eine Hintergrundverarbeitung erfolgen. Von einer ähnlichen Stelle in dem bestehenden Programm habe ich mir die Vorgehensweise abgeschaut. Zum Testen habe ich das Ganze so weit wie möglich auf das Westentliche reduziert. Auf Buttonklick erzeugt das Programm den Thread, der einfach von 0 bis 90 hochzählt und das Ergebnis in einem Memo des Fensters ausgibt. Mein Problem ist, daß ich bei der Ausführung des Thread relativ oft eine Zugriffsverletzung bekomme. Das passiert in zwei Arten: Meldung Access Violation und Meldung

Gtk-WARNING **: Invalid text buffer iterator: either the iterator is uninitialized, or the characters/pixbufs/widgets in the buffer have been modified since the iterator was created.
You must use marks, character numbers, or line numbers to preserve a position across buffer modifications.
You can apply tags and insert marks without invalidating your iterators,
but any mutation that affects 'indexable' buffer contents (contents that can be referred to by character offset)
will invalidate all outstanding iterators

an der Konsole

oder Programm wird sofort ohne irgendwelche Meldungen beendet und Ausgabe an der Konsole

Gtk:ERROR:gtktextview.c:3571:gtk_text_view_validate_onscreen: assertion failed: (text_view->onscreen_validated)
Abgebrochen


Anbei das Fenster, wo das Problem auftritt.

Hat jemand einen Tip, was da noch falsch ist (vielleicht ja nur was ganz banales) ?
Dateianhänge
mycluster20140412b.zip
(2.26 KiB) 52-mal heruntergeladen
Jürgen

Christian
Beiträge: 6079
Registriert: Do 21. Sep 2006, 07:51
OS, Lazarus, FPC: iWinux (L 1.x.xy FPC 2.y.z)
CPU-Target: AVR,ARM,x86(-64)
Wohnort: Dessau
Kontaktdaten:

Re: Thread Zugriffsverletzung

Beitrag von Christian »

Ich hab jetzt aus purer Faulheit nicht in den Code geschaut.

Du musst bei Aufrifen aus einem Thread mit dem Hauptprogramm synchronisieren. Du darfst nicht ohne zu Synchronisieren auf Elemente des Hauptprogramms zugreifen. Das machst du mit Synchronize. Ich nehm mal an du hast das nicht getan ?!
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/

CFJH
Beiträge: 3
Registriert: Sa 12. Apr 2014, 19:02
OS, Lazarus, FPC: Suse (L 1.0.10 FPC 2.6.2)
CPU-Target: 64Bit
Wohnort: Erde
Kontaktdaten:

Re: Thread Zugriffsverletzung

Beitrag von CFJH »

Ich syncronisiere die Ausgabe des Memos mit Enter/Leave-criticalsection(arg), wobei die Variable im public des Formulares ist und bei oncreate initialisiert wird.
Jürgen

Benutzeravatar
theo
Beiträge: 10869
Registriert: Mo 11. Sep 2006, 19:01

Re: Thread Zugriffsverletzung

Beitrag von theo »

CFJH hat geschrieben:Ich syncronisiere die Ausgabe des Memos mit Enter/Leave-criticalsection(arg), wobei die Variable im public des Formulares ist und bei oncreate initialisiert wird.
Das ist nicht dasselbe. Du musst Synchronize verwenden.
http://wiki.lazarus.freepascal.org/Mult ... se_TThread

CFJH
Beiträge: 3
Registriert: Sa 12. Apr 2014, 19:02
OS, Lazarus, FPC: Suse (L 1.0.10 FPC 2.6.2)
CPU-Target: 64Bit
Wohnort: Erde
Kontaktdaten:

Re: Thread Zugriffsverletzung

Beitrag von CFJH »

Das Schreiben des Memos wurde nur durch ...criticalsection() umgeben.
Jetzt habe ich das auch über Synchronize gemacht und bis jetzt sind keine Fehler mehr aufgetreten.
Das fehlende Synchronize für das Memo war wohl das Problem.
Jürgen

Christian
Beiträge: 6079
Registriert: Do 21. Sep 2006, 07:51
OS, Lazarus, FPC: iWinux (L 1.x.xy FPC 2.y.z)
CPU-Target: AVR,ARM,x86(-64)
Wohnort: Dessau
Kontaktdaten:

Re: Thread Zugriffsverletzung

Beitrag von Christian »

Mit der Criticalsection stellst du nur sicher, das mehrere deiner Thread nicht gleichzeitig aufs Memo zugreifen. Wenn das Hauptprogramm gleichzeitig aufs Memo zugreift knallts. Deshalb Synchronize.
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: Thread Zugriffsverletzung

Beitrag von mschnell »

Vielleicht sollte man dem Fragesteller doch mitteilen, dass der Aufruf jedwede GUI Aktivität in einem Worker Thread verboten ist und "TThread.Sychronize" und "TThread.Queue" es erlauben, von einem Worker Thread aus den Main Thread dazu aufzufordern die übergebene Funktion aufzurufen (sobald der dazu Zeit hat).

-Michael
Zuletzt geändert von mschnell am So 13. Apr 2014, 10:38, insgesamt 1-mal geändert.

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: Thread Zugriffsverletzung

Beitrag von mschnell »

Christian hat geschrieben:Mit der Criticalsection stellst du nur sicher, das mehrere deiner Thread nicht gleichzeitig aufs Memo zugreifen. Wenn das Hauptprogramm gleichzeitig aufs Memo zugreift knallts. Deshalb Synchronize.
Es ist niemals möglich, dass mehrere Threads auf ein Memo zugreifen (egal ob gleichzeitig oder nacheinander). TMemo ist eine Klasse, die die GUI benutzt, und darf deshalb grundsätzlich nur in einem einzigen Thread zugegriffen werden: dem Mainthread der Application. (Das "Hauptprogramm" (also der User-Code, der von den entsprechenden "On..." Events aufgerufen wird) ist übrigens auch ein Thread, der tatsächlich auch mit Critical Section ausgesperrt werden kann.) Deshalb ist es vollkommen unsinnig, um Memo-Zugriff eine Critical Section zu bauen. Das Problem liegt hier auch nicht an Zugriffs-Konflikten im User-Code, sondern an der Machart der Lazarus Library (LCL) die (aus guten Gründen) so (vereinfacht) gebaut ist, dass sehr viele Funktionen nur im Mainthread erlaubt sind (siehe entsprechende Doku). Ein Einsteiger kann das natürlich nicht wissen.

-Michael

Antworten