Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Die Delphi-IDE (https://www.delphipraxis.net/62-die-delphi-ide/)
-   -   Allen Bauer: TThread Suspend/Resume ein "kolossaler Fehler" (https://www.delphipraxis.net/138020-allen-bauer-tthread-suspend-resume-ein-kolossaler-fehler.html)

mjustin 2. Aug 2009 09:30


Allen Bauer: TThread Suspend/Resume ein "kolossaler Feh
 
Kleine Umfrage:

wer wußte, dass die Methoden Suspend und Resume der Klasse TThread unsicher sind?

Allen Bauer schreibt im News Forum Beitrag "Fatal Threading Model!" (https://forums.codegear.com/message....ssageID=142516), dass die Aufnahme der Methoden Suspend und Resume in der TThread Klasse ein "kolossaler Fehler" war, der viele in die Irre geführt hat, und entschuldigte sich bei allen, bei denen es durch Verwendung dieser Methoden zu Problemen gekommen ist:

Zitat:

I fully admit that the inclusion of Suspend/Resume on TThread was a collosal mistake and has led many astray. I would rather work to rectify that mistake. My most sincere appology to all who have been bitten by any issue through the use of those methods.
Die Diskussion wurde ausgelöst durch Probleme, die durch einen bereits länger bekannten Fehler entstanden, und drehte sich auch um die Frage welche Kriterien verwendet werden um die Priorität eines Bugreports zu bestimmen.

Hier der QC Eintrag:
Using TThread.Resume may cause setting freed object value
http://qc.codegear.com/wc/qcmain.aspx?d=26291)

mirage228 2. Aug 2009 10:41

Re: Allen Bauer: TThread Suspend/Resume ein "kolossaler
 
Vielleicht hilft Dir ja dieser Artikel aus der JDK weiter:
Why Are Thread.stop, Thread.suspend,
Thread.resume and Runtime.runFinalizersOnExit Deprecated?

mjustin 2. Aug 2009 10:48

Re: Allen Bauer: TThread Suspend/Resume ein "kolossaler
 
Zitat:

Zitat von mirage228

Gerne gelesen - ja wenn Delphi denn bei Resume einen Deadlock haben würde, das könnte man dann leichter auf die Ursache zurückführen. Der Bug führt jedoch zu einem schwer zu lokalisierenden Problem durch Überschreiben von Speicher:

Zitat:

"Even FastMM with FullDebugMode can't report the exact location of the bug. FastMM can only report that one of the
previous operations has corrupted memory."

himitsu 2. Aug 2009 11:43

Re: Allen Bauer: TThread Suspend/Resume ein "kolossaler
 
Was für ein Glück, daß ich meine Threads immer sich selber an "definierter" Stelle in die Pause schicken lasse. :angel:

Also wenn ich das richtig verstehe, dann kommt es zu Problemen, wenn der Thread wärend der Manipulation von threadübergreifenden gemeinsam genutzten Resourcen pausiert wird und somit diese Operationen nicht beendet? :gruebel:

jaenicke 2. Aug 2009 12:04

Re: Allen Bauer: TThread Suspend/Resume ein "kolossaler
 
Das Problem ist soweit ich das eben überflogen habe, das Resume zuerst den Thread fortsetzt und dann weitere Befehle ausführt. Der Thread selbst kann dort aber schon beendet und dann freigegeben sein, woraufhin der letzte Befehl, der ein privates Feld setzt, auf freigegebenen Speicher schreibt.

Ich verstehe allerdings nicht so ganz:
  • Erstens warum man Threads benutzt, die so schnell fertig sind. (äußerst ineffizient)
  • Und warum man zweitens einen eigenen Thread schreiben sollte, der sich im Konstruktor suspended erzeugt und dann selbst fortsetzt. Dass solch ein seltsames Konstrukt Probleme machen kann, damit hätte ich eigentlich direkt gerechnet...
Deshalb sind die Fälle, in denen ich Threads einsetze, von den Problemen nicht betroffen soweit ich das sehe. Und ich hatte bisher damit auch keine Probleme.

mjustin 2. Aug 2009 14:50

Re: Allen Bauer: TThread Suspend/Resume ein "kolossaler
 
Zitat:

Zitat von jaenicke
Ich verstehe allerdings nicht so ganz:[list][*]Erstens warum man Threads benutzt, die so schnell fertig sind. (äußerst ineffizient)

Der Fehler tritt häufiger auf, wenn viele Threads gestartet und beendet werden - also zum Beispiel in einer Serveranwendung, die viele Requests von verschiedenen Clients parallel verarbeitet. Die Wahrscheinlichkeit, dass einer der Threads bereits das Free ausgeführt hat bevor auf seine Instanzvariable zugegriffen wird, hängt auch von der Last (Anzahl Threads) ab. Die absolute Ausführungszeit des Threads ist für das Auftreten des Bugs nicht entscheidend. Kritisch wird es, sobald diese Zeit kleiner als die Zeit ist, die zwischen der Ausführung von zwei Stellen in der Resume Methode vergeht:

Zitat:

The problem is, if there are many threads created and freed, the delay after ResumeThread(FHandle) could be big enough for the thread to finish and free itself before the routine arrives at FSuspended := False.
http://qc.embarcadero.com/wc/qcmain.aspx?d=26291

jbg 2. Aug 2009 15:17

Re: Allen Bauer: TThread Suspend/Resume ein "kolossaler
 
Zitat:

Zitat von mjustin
wer wußte, dass die Methoden Suspend und Resume der Klasse TThread unsicher sind?

Ich. Wobei Suspend nicht unsicher ist. Man darf es nur nicht außerhalb des Threads nutzen (da man nicht weiß wo man den Thread gerade anhält). Und das (eigenliche) Problem mit Resume kenne ich seit ich meine AsyncCalls.pas Unit vor ein paar Jahren geschrieben habe. FreeOnTerminate+Resume ist tötlich.

jaenicke 2. Aug 2009 15:20

Re: Allen Bauer: TThread Suspend/Resume ein "kolossaler
 
Stimmt, an eine echte Multithread-Serveranwendung hatte ich jetzt nicht gedacht. Da kann das natürlich vorkommen. Allerdings würde ich da die aktuellen Requests eigentlich ohnehin manuell verwalten und nicht einfach "zufällig" beim Ende irgendwo selbst sich freigeben lassen.

mjustin 2. Aug 2009 16:27

Re: Allen Bauer: TThread Suspend/Resume ein "kolossaler
 
Zitat:

Zitat von jaenicke
[*]Und warum man zweitens einen eigenen Thread schreiben sollte, der sich im Konstruktor suspended erzeugt und dann selbst fortsetzt. Dass solch ein seltsames Konstrukt Probleme machen kann, damit hätte ich eigentlich direkt gerechnet...[/list]

Wenn ich die Newsgroup richtig gelesen habe, war es damit leichter, den Fehler zu reproduzieren. Ob Resume innerhalb oder ausserhalb des Konstruktors aufgerufen wird, spielt für den Bug aber keine Rolle:

Zitat:

In my test app I call resume from outside the constructor with same results. The difference is that by calling it from within the constructor it is easier to reproduce the bug.
(Die erwähnte Testanwendung ist in der Attachment-Newsgroup zu finden)


Alle Zeitangaben in WEZ +1. Es ist jetzt 00:04 Uhr.

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