Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi probleme mit threads (https://www.delphipraxis.net/27059-probleme-mit-threads.html)

nailor 3. Aug 2004 16:33


probleme mit threads
 
Liste der Anhänge anzeigen (Anzahl: 2)
also folgendes problem:

ich will was mit threads machen. klappt auch wunderbar, ich rufe in der "execute"-methode "dosomething" auf.

wenn ich "dosomething" mit "Synchronize(dosomething)" aufrufe klappt es bis zum letzten befehl in "dosomething" (das showmessage das ich da platziert habe, kommt noch). dann kommt allerdings eine AccessViolation (siehe bild 1, absoult nichtssagen). das showmessage, dass in der "execute"-methode dann folgt wird logischerweiße nicht mehr ausgeführt.

lasse ich das "Synchronize" weg, dann schmiert er schon mitten in der "dosomething"-methode ab. (siehe bild 2 - ich hab allerdings weit und breit keine leinwand und auch kein bild, nur filestreams)

--> warum krepiert mein thread beim sich beenden?


edit: die beiden (nichtssagenden) bilder hochgeladen
edit2&3: richtige bilder hochgeladen

nailor 3. Aug 2004 17:45

Re: probleme mit threads
 
ich hab jetzt mal ein dynamisches array in der funktion (dosomething) durch ein festes array ersetzt --> es klappt (noch nicht ganz, aber ich bekomme zumindest keine accessviolation mehr)

ich melde mich nochmal falls es ganz funktioniert, oder ich nicht mehr weiterkomm. hat einer ne ahnung woran das liegen könnte? und nein, es war kein indexoutofbounds!!!

nailor

Sanchez 3. Aug 2004 17:59

Re: probleme mit threads
 
Hi,

Die Meldung "Leinwand/Bild erlaubt kein Zeichnen" bedeutet, dass du im Thread irgendeine Zeichenoperation (Invalidate oder ähnliches) auslöst, während die Zeichenfläche durch den Hauptthread blockiert ist, oder umgekehrt. Auf die GUI solltest du nicht gleichzeitig aus 2 Threads zugreifen. Die VCL ist da nicht unbedingt threadsicher.

Wenn du im Execute vom Thread nur eine Funktion mit Syncronize aufrufst, dann verhält sich das ganze eigentlich so, als ob nicht mit Threads arbeitest.

Versuchs mal mit MessageBox anstatt mit mit ShowMessage. Wie bereits erwähnt ist die VCL nicht wirklich threadsicher.

grüße, daniel

nailor 3. Aug 2004 18:04

Re: probleme mit threads
 
sehe ich das richtig: synchronize sollte man nicht nehmen, wenn nicht undedingt nötig, da es das thread-system unterwandert?
der zweite fehler kam, weil ich zweimal auf einmal auf die gui zugegriffen habe?

Sanchez 3. Aug 2004 18:48

Re: probleme mit threads
 
Zitat:

Zitat von nailor
sehe ich das richtig: synchronize sollte man nicht nehmen, wenn nicht undedingt nötig, da es das thread-system unterwandert?

Ganz genau. Synchronize ist für die Kommunikation des Threads mit der Außenwelt zuständig.
Wie der Name schon sagt wird der Thread dabei mit dem Hauptthread synchronisiert, also muss er warten.

Zitat:

Zitat von nailor
der zweite fehler kam, weil ich zweimal auf einmal auf die gui zugegriffen habe?

Höchstwahrscheinlich. Ein Thread hat einen Canvas gelockt und ein anderer wollte darauf zeichnen.

nailor 3. Aug 2004 19:38

Re: probleme mit threads
 
gut hab es jetzt am laufen *froi*

jetzt allerdings nochmal zum "kommunizieren mit der außenwelt": angenommen, mein thread soll regelmäßig irgendwelche lebenszeichen und fortschrittsangaben nach außen funken. ist es dann am geschicktesten, die rechen-methode normal (ohne synchro) laufen zu lassen, und von zeit zu zeit über "synchronize(IchLebeNoch(UndDasIstMeinFortschritt) )" dem hauptteil meines programmes bescheidzusagen, wie es um den thread steht?
und wie kann ich im hauptprogramm rausfinden, ob der thread noch am laufen its, oder nicht. irgendwie hab ich keine möglichkeit gefunden, außer dass der thread selbst vor dem beenden bescheid gibt, aber dann ist er ja noch nicht ganz fertig...

NicoDE 3. Aug 2004 19:46

Re: probleme mit threads
 
Zitat:

Zitat von nailor
jetzt allerdings nochmal zum "kommunizieren mit der außenwelt": angenommen, mein thread soll regelmäßig irgendwelche lebenszeichen und fortschrittsangaben nach außen funken. ist es dann am geschicktesten, die rechen-methode normal (ohne synchro) laufen zu lassen, und von zeit zu zeit über "synchronize(IchLebeNoch(UndDasIstMeinFortschritt) )" dem hauptteil meines programmes bescheidzusagen, wie es um den thread steht?
und wie kann ich im hauptprogramm rausfinden, ob der thread noch am laufen its, oder nicht. irgendwie hab ich keine möglichkeit gefunden, außer dass der thread selbst vor dem beenden bescheid gibt, aber dann ist er ja noch nicht ganz fertig...

Am performantesten wird es sein, die Statusinformationen in eine Variable zu schreiben (dessen Adresse man zum Beispiel dem Thread als Property mitgeben kann oder die statisch sein könnte falls nur ein Thread läuft...).
Dann wird der Thread nur solange aufgehalten, wie die Variable durch das Auslesen des Hautpthreads blockiert ist (dass die Variable/Struktur zum Lesen/Schreiben gelockt wird, setze ich einfach mal als selbstverständlich voraus :)).


Gruss Nico

nailor 3. Aug 2004 19:52

Re: probleme mit threads
 
meine idee -> thread ruft funktion im hauptprogramm auf und übergibt parameter

deine idee -> hauptprogramm liest variable des threads aus


neue idee von mir -> thread schreibt varialbe im hauptprogramm


------

wie ist es am geschicktesten zu regeln? und das zweite ist: wie kann ich am sinnvollsten rausfinden, ob mein thread noch am laufen ist?

idee -> vor dem schließen noch eine "ich schließe jetzt" statusmeldung absetzen

andere ideen -> ?

NicoDE 3. Aug 2004 20:06

Re: probleme mit threads
 
Zitat:

Zitat von nailor
deine idee -> hauptprogramm liest variable des threads aus

Eher: Hauptprogramm liesst Variable, welche vom Thread geschrieben wird.

Letztendlich läuft alles darauf hinaus, die Anzeige von der Funktionalität zu trennen.

Zur letzten Frage: Es gibt eine Eigenschaft von TThread, die vorgibt, ob das Thread-Objekt beim Beenden automatisch freigeben werden soll (Name hab ich vergessen). Wenn das deaktiviert wurde, kannst Du jederzeit Abfragen ob der Thread bereits fertig ist (sonst würde es eine Excepton, beim Versuch auf das freigegebene Objekt zuzugreifen, geben...).


Gruss Nico

ps: Wenn es sich bei der Status-Variablen um einen Integer handelt (Prozent, oder was auch immer), dann reichen die InterlockedXxx-Funktionen aus und man muss nicht noch ein Locking-Objekt für die Status-Struktur einführen.

nailor 3. Aug 2004 20:14

Re: probleme mit threads
 
trennen (anzeige/rechnen): ok, ist bei mir oft eh so eingerichtet

über ne exception zu testen, ob was noch da ist... na ja. dann nehm ich lieber die version, die testet, ob der fortschritt komplett durchgelaufen ist

das mit interlocked schau ich mir mal an, hört sich gut an. von einem locking objekt hab ich keine ahnung. vielleicht lern ichs ja jetzt ;)

nailor

NicoDE 3. Aug 2004 20:22

Re: probleme mit threads
 
Zitat:

Zitat von nailor
über ne exception zu testen, ob was noch da ist...

Eben das sollst Du ja nicht machen :)
Sieh Dir mal FreeOnTerminate und OnTerminate an (letzteres wird IIRC mit dem Haupt/VCL-Thread synchronisiert).

Zitat:

Zitat von nailor
von einem locking objekt hab ich keine ahnung.

Es gibt kein Locking-Objekt (ok, es gibt fertige Objekte in der Delphi-RTL dafür). Ich meinte damit nur, dass man den gemeinsamen Zugriff auf eine Variable durch was auch immer (Locking :)) synchronisieren muss. Entweder man benutzt dafür eine fertige Klasse (Namen vergessen) oder bei Integern die Win32 API-Funktionen InterlockedExchange und Konsorten...

nailor 3. Aug 2004 20:28

Re: probleme mit threads
 
terminate: werd mir was einfallen lassen

locking: am anfang um den thread zu initialisieren werde ich mir wohl über "synchronize" ein paar daten aus dem hauptprogramm ziehen. der rest (eine gelegentliche rückmeldung) sollte über interlockXXX klappen. allerdings erklär mir mal einer den sinn hiervon:

Zitat:

InterlockedIncrement (Funktion)

Die Funktion inkrementiert zwei Integer-Werte thread-sicher.

Unit

SysUtils

Kategorie

Thread-Verwaltung

Delphi-Syntax:

function InterlockedIncrement(var I: Integer): Integer;

C++ Syntax:

extern PACKAGE int __fastcall InterlockedIncrement(int &I);

Beschreibung

InterlockedIncrement inkrementiert die in I übergebene Variable so, dass während dieser Operation kein Zugriff durch andere Threads möglicht ist. Der Rückgabewert hat dasselbe Vorzeichen wie das inkrementierte Ergebnis, aber nicht zwangsläufig einen identischen Wert.

Die in der Unit SysUtils definierte Funktion InterlockedIncrement ist nur unter Linux verfügbar. Unter Windows verwenden Anwendungen die Win32-API mit demselben Namen.
ich glaub ich mach jetzt schluss für heute. oder zumnidest mal pause...

NicoDE 3. Aug 2004 20:38

Re: probleme mit threads
 
Zitat:

Zitat von nailor
allerdings erklär mir mal einer den sinn hiervon

Die Funktion gibt den, um eins, erhöhten Wert zurück.
Da auch ein anderer Thread der Variable gerade Inkrementieren kann, ist nach folgendem Code (der nicht nur Nachahmung empfohlen ist!):
Delphi-Quellcode:
if i = 42 then
  i := InterlockedIncrement(i);
...der Wert von i nicht zwangsläufig 43.

Kurz, Du kannst keine Annahmeen über den Wert machen - und solltest/kannst nur die Interlocked-Funktionen zum Auslesen/Setzen verwenden.

nailor 4. Aug 2004 00:08

Re: probleme mit threads
 
:wall: so, hab jetzt ne in meinen augen zum fortschritt übermitteln sehr schöne methode gefunden: ich feuer einfach von zeit zu zeit ne windowsmessage ab, nach dem motto

PostMessage(mainhandle, WM_USER, bla, blubb);

da es sich ja nicht um daten handelt, mit denen zeitkritisch weitergearbeitet werden soll, sondern nur der förmliche antrag an die hauptform mal ne progressbar nen stück rüberzuschieben, glaube ich ist das so ziemlich gut.

nailor

Luckie 4. Aug 2004 14:58

Re: probleme mit threads
 
Und as mit dem "Leinwand erlaubt kein zeichen" liegt an der VCL, da selbige nicht threadsafe ist. Ersetz mal dein ShowMessage durch MSDN-Library durchsuchenMessagebox, dann sollte es gehen.

Sanchez 4. Aug 2004 16:53

Re: probleme mit threads
 
Zitat:

Zitat von Luckie
Und as mit dem "Leinwand erlaubt kein zeichen" liegt an der VCL, da selbige nicht threadsafe ist. Ersetz mal dein ShowMessage durch MSDN-Library durchsuchenMessagebox, dann sollte es gehen.

Wie es bereits in meinem ersten Post dieses Threads geschrieben steht :mrgreen:

nailor 4. Aug 2004 17:22

Re: probleme mit threads
 
stimmt schon. das gleiche scheint auch noch für so nen kram wie MessageDlg und konsorten zu gelten. aber das eigentliche problem (welches sich mittlerweile in wohlgefallen aufgelöst hat) muss ein anderes gewesen sein, da ich die showmessages nur zum debuggen eingebaut hatte.

so langsam find ich mich in die DOs und DONTs der threaderei hinein.

Luckie 4. Aug 2004 18:32

Re: probleme mit threads
 
Delphi-Referenz durchsuchenMessageDlg ist auch eine VCL-Form. MSDN-Library durchsuchenmessagebox ist die Messagebox von Windows direkt.

nailor 4. Aug 2004 19:37

Re: probleme mit threads
 
ich hab schon kapiert. alle dialoge werden jetzt so ersetzt, dass sie keinen stopp des haupt-threads mehr erzwingen

nailor 4. Aug 2004 21:20

Re: probleme mit threads
 
problem: ich brauch ne messagebox mit:

Code:
ja
nein
ja zu allen
nein zu allen
das windows-dingen bietet nur

Code:
MB_ABORTRETRYIGNORE   The message box contains three push buttons: Abort, Retry, and Ignore.
MB_OK   The message box contains one push button: OK. This is the default.
MB_OKCANCEL   The message box contains two push buttons: OK and Cancel.
MB_RETRYCANCEL   The message box contains two push buttons: Retry and Cancel.
MB_YESNO   The message box contains two push buttons: Yes and No.
MB_YESNOCANCEL   The message box contains three push buttons: Yes, No, and Cancel.
das ist zu wenig. wie mach ich mir das jetzt am einfachsten?

nailor 5. Aug 2004 17:56

Re: probleme mit threads
 
keiner ne idee, wie ich eine threadsichere abfrage mit den vier antwortmöglichkeiten machen kann?

und @daniel:

Zitat:

Allgemeiner Fehler


Could not insert search results

DEBUG MODE

SQL Error : 1062 Duplicate entry '639115450' for key 1

INSERT INTO phpbb_delphisearch_results (search_id, session_id, search_array) VALUES(639115450, '###censored###', 'a:15:{s:14:"search_results";s:122:"5709, 8602, 10305, 10500, 10647, 10988, 11443, 15052, 19166, 21375, 21775, 23478, 23609, 24766, 26097, 26744, 27511, 28743";s:17:"total_match_count";i:18;s:12:"split_s earch";a:1:{i:0;s:13:"messagedialog";}s:7:"sort_by ";i:0;s:8:"sort_dir";s:4:"DESC";s:12:"show_results ";s:6:"topics";s:12:"return_chars";i:300;s:12:"sea rch_forum";i:-1;s:10:"search_cat";i:-1;s:13:"search_author";s:0:"";s:12:"search_terms"; i:1;s:13:"search_fields";i:1;s:11:"search_time";i: 0;s:16:"return_postcount";i:100;s:15:"found_stopwo rds";a:0:{}}')

Line : 1118
File : /www/htdocs/dpnethq/search.php



nailor 8. Aug 2004 11:07

Re: probleme mit threads
 
*push*

wie bekomm ich denn jetzt so eine DialogBox mit benutzerdefinierten Antorten, oder zumindest mit den Möglichkeiten ja/nein/alle/keine hin?

Luckie 8. Aug 2004 13:25

Re: probleme mit threads
 
Du könntest es von Hand direkt mit der WinAPI ohne VCL machen.

nailor 8. Aug 2004 19:18

Re: probleme mit threads
 
werd ich wohl machen müssen...

soll ich dabei von einem ganz normalen leeren fenster ausgehen (so, wie wenn man bei einem typischen nonvcl-programm ein fenster erstellt), oder gibt es irgendeine weiterentwickelte vorlage, die ich nutzen könnte?


Alle Zeitangaben in WEZ +1. Es ist jetzt 06:25 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz