AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

[Thread] Thread im Deadlock abschießen

Ein Thema von s.h.a.r.k · begonnen am 10. Okt 2008 · letzter Beitrag vom 10. Okt 2008
Antwort Antwort
Benutzerbild von s.h.a.r.k
s.h.a.r.k

Registriert seit: 26. Mai 2004
3.159 Beiträge
 
#1

[Thread] Thread im Deadlock abschießen

  Alt 10. Okt 2008, 00:07
guten abend alle miteinander,

ich hoffe, es gibt eine lösung für das folgende problem. und zwar geht es darum, dass wenn ein thread mal in einem deadlock endet, da dieser beispielsweise auf einen anderen wartet, dann würde ich diesen gerne "abschießen" wollen, d.h. ihn abbrechen und neu starten. ich habe mir vorgestellt, das dies "einfach" (*hust*, sonst würde ich hier ja nicht posten) ein .Free oder dergleichen erledigt, aber pustekuchen. habe mir eine anwendung geschrieben, mit der ich das testen kann, aber ich finde keine passende methode dafür, die das übernehmen kann.

ich hoffe jemand von euch hat mir hier eine lösung. mir ist klar, dass "es geht nicht" auch eine lösung ist, aber ich denke, da muss es doch eine möglichkeit geben. ich denke dabei allgemein an eine regenerative anwendung, die sich selbst überwacht und passend die internen "prozesse" neu startet.

mit freundlichen grüßen
armin
»Remember, the future maintainer is the person you should be writing code for, not the compiler.« (Nick Hodges)
  Mit Zitat antworten Zitat
Dezipaitor

Registriert seit: 14. Apr 2003
Ort: Stuttgart
1.701 Beiträge
 
Delphi 7 Professional
 
#2

Re: [Thread] Thread im Deadlock abschießen

  Alt 10. Okt 2008, 01:01
Du solltest deine Wartestrategie auf andere Threads überdenken. Warte nicht unendlich sondern nur eine bestimmte Zeit. Oder du nutzt WaitForMultipleObjects und wartest auf den anderen Thread UND auf ein Stopsignal.
Und dann ganz am Ende kannst du immernoch TerminateThread nutzen.
Christian
Windows, Tokens, Access Control List, Dateisicherheit, Desktop, Vista Elevation?
Goto: JEDI API LIB & Windows Security Code Library (JWSCL)
  Mit Zitat antworten Zitat
alzaimar
(Moderator)

Registriert seit: 6. Mai 2005
Ort: Berlin
4.956 Beiträge
 
Delphi 2007 Enterprise
 
#3

Re: [Thread] Thread im Deadlock abschießen

  Alt 10. Okt 2008, 07:33
Wenn man das Objekt/Handle, auf das der Thread mit 'WaitForXXXObject' wartet, per 'CloseHandle' schließt, dann liefert die 'WaitXX' Routine den Wert 'WAIT_ABANDONED'.

Aber Dezipaitor hat Recht: Wenn Du in so eine Situation kommst, dann i.A. stimmt etwas nicht. Nur wenn Du zum Programmende alle Threads beenden willst, ist das imho legitim.

Du kannst auch den 'Terminated' Flag des Threads setzen und dann am Handle (z.B. der Semaphore) zupfen. Dann kommt das 'Wait' zurück und Du kannst als Erstes das 'Terminated' Flag prüfen.
"Wenn ist das Nunstruck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput!"
(Monty Python "Joke Warefare")
  Mit Zitat antworten Zitat
Benutzerbild von mirage228
mirage228

Registriert seit: 23. Mär 2003
Ort: Münster
3.750 Beiträge
 
Delphi 2010 Professional
 
#4

Re: [Thread] Thread im Deadlock abschießen

  Alt 10. Okt 2008, 08:21
Falls Du den Thread abschießen willst, geht das mit MSDN-Library durchsuchenTerminateThread.

Das sollte aber nur das letzte Mittel sein ...
David F.

May the source be with you, stranger.
PHP Inspection Unit (Delphi-Unit zum Analysieren von PHP Code)
  Mit Zitat antworten Zitat
Benutzerbild von Flocke
Flocke

Registriert seit: 9. Jun 2005
Ort: Unna
1.172 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#5

Re: [Thread] Thread im Deadlock abschießen

  Alt 10. Okt 2008, 17:56
Probier mal die folgenden Routinen, die Funktionsweise ist mir letztens eingefallen. Ich erzeuge einfach eine Exception in dem angegebenen Thread. Ist auch nicht 100%-ig sauber, aber immer noch besser als TerminateThread, besonders wenn die Dinge im Thread schön mit try..finally umklammert sind.

Delphi-Quellcode:
unit ThreadAbort;

interface

uses
  Windows, SysUtils, Classes;

{ These functions raise the given exception inside the given thread.
  The underscore variant simply returns False/True to indicate the success or
  failure of the action, while the other two raise an EOSError on that.
}

function _RaiseInThread(Which: THandle; E: Exception): Boolean;
procedure RaiseInThread(Which: THandle; E: Exception); overload;
procedure RaiseInThread(Which: TThread; E: Exception); overload;

{ These functions raise an EThreadAbort exception inside the given thread.
}

type
  EThreadAbort = class(Exception);

procedure AbortThread(Which: THandle; const Message: string = ''); overload;
procedure AbortThread(Which: TThread; const Message: string = ''); overload;

implementation

{ Raise an exception in the given thread.
}

function _RaiseInThread(Which: THandle; E: Exception): Boolean;
var
  Context: TContext;

  procedure Push(c: DWORD);
  begin
    Dec(Context.Esp, SizeOf(DWORD));
    PCardinal(Context.Esp)^ := c;
  end;

begin
  if Which = GetCurrentThread then
    raise E;

  Result := False;
  if SuspendThread(Which) = DWORD(-1) then
    Exit;
  try
    Context.ContextFlags := CONTEXT_CONTROL or CONTEXT_INTEGER;
    if not GetThreadContext(Which, Context) then
      Exit;

    { The following lines are copied from System.pas / _RaiseExcept,
      which (sadly) cannot be called directly. It uses the same calling
      convention since Delphi 3 (Delphi 2 uses a different signature).
    }

    Push(Context.Esp);
    Push(Context.Ebp);
    Push(Context.Edi);
    Push(Context.Esi);
    Push(Context.Ebx);
    Push(DWORD(E)); { pass class argument         }
    Push(Context.Eip); { pass address argument       }

    Push(Context.Esp); { pass pointer to arguments   }
    Push(7); { there are seven arguments   }
    Push(1); { cNonContinuable:  we can't continue execution }
    Push($0EEDFADE); { cDelphiException: our magic exception code    }
    Push(Context.Eip); { pass the return address     }

    {$IFDEF CONDITIONALEXPRESSIONS} // Delphi 6+
    Context.Eip := DWORD(RaiseExceptionProc);
    {$ELSE}
    Context.Eip := DWORD(@RaiseException);
    {$ENDIF}

    if SetThreadContext(Which, Context) then
      Result := True;
  finally
    if ResumeThread(Which) = DWORD(-1) then
      Result := False;
  end;
end;

procedure RaiseInThread(Which: THandle; E: Exception);
begin
  if not _RaiseInThread(Which, E) then
    RaiseLastOSError;
end;

procedure RaiseInThread(Which: TThread; E: Exception);
begin
  RaiseInThread(Which.Handle, E);
end;

procedure AbortThread(Which: THandle; const Message: string);
begin
  RaiseInThread(Which, EThreadAbort.Create(Message));
end;

procedure AbortThread(Which: TThread; const Message: string);
begin
  AbortThread(Which.Handle, Message);
end;

end.
Gib kurz Bescheid wenn was fehlt, ich habe den Code aus einer größeren Unit herauskopiert.
Volker
Besucht meine Garage
Aktuell: RtfLabel 1.3d, PrintToFile 1.4
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:33 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