|
Trouver une ressource
Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum. Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !
Sujet : question sur les thread [ Divers / Aide et documentation ] (Sat83)
Informations & options pour cette discussion
|
lundi 21 avril 2008 à 18:06:03 |
question sur les thread

Sat83
|
Bonjour a tous, J'ai une petite interrogation concernant les threads. Je souhaite arreter mon application a une heure précise. Mon programme fonctionne parfaitement, et actuellement j'utilise un TTimer avec un Interval de 10 secondes qui regarde que l'heure fixée n'est pas arrivée. Si elle est arrivée, l'application se ferme. Jusqu'ici tous va bien. Le problème c'est que si mon application plante ou reste bloqué dans un traitement (ca ne devrait pas arrivé, mais on ne sais jamais), elle restera bloqué et elle ne se fermera pas a l'heure (puisque l'application etant planté, elle n'ira pas dans la procédure du Timer). En gros je voudrais que le thread tourne en boucle en attendant la bonne heure, et que lorsque celle ci arrive, elle ferme l'application ou force la fermeture si l'appli est plantée. Je me demande donc si je remplace la fonction du Timer par un thread parallèle, est ce que cela marchera même si le thread principale est planté? Ou est ce que cette solution ne vous semble pas correcte (je connais pas encore bien les threads et leurs comportements)? Merci d'avance
|
|
|
|
lundi 21 avril 2008 à 18:38:13 |
Re : question sur les thread

florenth
|
Salut !
Si ton thread principal est planté (genre boucle infinie) ou ne vérifie pas périodiquement l'existence de signaux provenant de l'autre thread, ta solution ne fonctionnera pas.
Cette solution que tu proposes est donc strictement identique à l'autre.
Si ton application est déjà multi-threadée, c'est la solution que je te conseille, sinon tu peux largement garder la version "timer" qui est tout à fait acceptable.
Ce que tu peux faire, par contre, c'est changer la propriété Interval du timer en fonction du temps restant avant la fermeture, pour moins consommer en ressources processeur (même si c'est pas énorme une fois toutes les 10 secondes)
Un truc du genre en gros :
var
TempsRestant: Double;
begin
TempsRestant := DateTimeDeFin - Now;
if TempsRestant <= 0 then
Close
else if TempsRestant <= 60 then
Timer.Interval := 5000
else if TempsRestant <= 120 then
Timer.Interval := 40000
else
Timer.Interval := 120*60;
end;
A+
Flo
|
|
|
|
lundi 21 avril 2008 à 18:39:57 |
Re : question sur les thread

florenth
|
J'avais pas vu un détail: "forcer la fermeture"
Dans ce cas, alors tu peux utiliser un thread qui appelle la fonction système qui "tue" les processus. Mais je ne sais pas si un processus peut s'auto-tuer, à essayer...
|
|
|
|
lundi 21 avril 2008 à 19:23:39 |
Re : question sur les thread

Sat83
|
Pour l'instant j'en suis a la solution avec le Timer.
J'envisage de passer a la solution avec un second thread, mais seulement si c'est utile. C'est pour cette raison que j'ai preféré poser la question avant de me lancer dans un developpement inutile qui m'aurait amené au même resultat.
Dans ce que j'imaginais comme solution, dans mon second thread je voulais soit fermer le programme normalement si c'est possible, soit killer le processus (en passant par un .bat intermediaire).
|
|
|
|
lundi 21 avril 2008 à 21:20:53 |
Re : question sur les thread

Caribensila
|
Bonsoir,
« Mais je ne sais pas si un processus peut s'auto-tuer » C'est possible. Dans ce test, le process s'auto-tue au bout de 4 secondes :
type TWaitThread = class(TTHread) private fProcessHndl : Thandle; // Handle du process. protected Constructor Create(Hndl : Thandle); procedure Execute; override; end; TForm1 = class(TForm) Button1: TButton; Edit1: TEdit; procedure Button1Click(Sender: TObject); end; var Form1: TForm1; implementation {$R *.dfm} var Wait : TWaitThread; Constructor TWaitThread.Create(Hndl : Thandle); begin fProcessHndl := Hndl; inherited Create(false); end; procedure TWaitThread.Execute; begin while not terminated do begin sleep(4000); //Le process se suicidera au bout de 4s. beep; // Dernier soupir. TerminateProcess(fProcessHndl, 0); //là, le process est décédé à 100%. end; end; procedure TForm1.Button1Click(Sender: TObject); var i : integer; begin Wait := TWaitThread.Create(GetCurrentProcess); // On lance le Thread. i := 1; repeat //Boucle à la con, mais infinie. Edit1.text := inttostr(i); Edit1.Refresh; inc(i); until i = -1; end;
|
|
|
|
lundi 21 avril 2008 à 21:31:49 |
Re : question sur les thread

Caribensila
|
... Mais le big problème dans tout ça, c'est que TerminateProcess ne libère aucune ressource...
|
|
|
|
mardi 22 avril 2008 à 08:46:07 |
Re : question sur les thread

Sat83
|
Merci pour ta solution!
Y'aurait-il un moyen de tenter de fermer le programme "normalement" dans le thread, de detecter si c'est pas possible, et dans ce cas là seulement forcer la fermeture avec TerminateProcess ?
|
|
|
|
mardi 22 avril 2008 à 12:29:35 |
Re : question sur les thread

Rematrix
|
Si j'été vous j'ivetrais de faire un terminateprocess, fermer comme ça brutement c pas trés propre éssez plus tôt d'envoyé un sms de type WM_CLOSE  ça feras la faire genre SendMessage( fProcessHndl , WM_CLOSE, 0, 0);. Matrix 
|
|
|
|
mardi 22 avril 2008 à 12:54:50 |
Re : question sur les thread

florenth
|
Bon alors d'après Cari, le processus peut d'auto tuer
Mais TerminateProcess() libère quand même toutes les ressources (et oui !) ***
Ce qu'il ne fait pas, c'est exécuter les procédures de "finalization", les OnDestroy(), etc...
Donc c'est pas propre si par exemple le programme veut pouvoir sauvegarder son fichier de configuration.
Donc, comme le demande Sat83, on peut ruser :
- Une première demande de fermeture "propre": le sms WM_CLOSE fonctionne parfaitement sur toutes les applications VCL Delphi (ce n'est pas forcément le cas pour les autres langages)
- Si au bout de... disons 5 secondes, le programme ne s'est toujours pas arrêté, on fait appel à TerminateProcess
*** : Quoi que j'ai tout de même un doute pour les fichiers ouverts.
|
|
|
|
mardi 22 avril 2008 à 13:19:12 |
Re : question sur les thread

florenth
|
Réponse acceptée !
Voila ce que ça donne (testé et approuvé par un échantillon de une personne) :
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TAutoTerminateThread = class(TThread)
private
FMainWndHandle: THandle;
FTerminateTime: TDateTime;
FWaitEvent: Cardinal;
protected
procedure Execute; override;
public
constructor Create(MainWindowHandle: THandle; EndTime: TDateTime);
destructor Destroy; override;
{ Obligé de réintroduire cette méthode car on utilise un TEvent,
ce qui n'est malheureusement pas géré nativement par Delphi }
procedure Terminate; reintroduce;
end;
TFrmTest = class(TForm)
BtnQuit: TButton;
BtnPlante: TButton;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure BtnQuitClick(Sender: TObject);
procedure BtnPlanteClick(Sender: TObject);
private
FTermThread: TAutoTerminateThread;
end;
var
FrmTest: TFrmTest;
implementation
{$R *.dfm}
constructor TAutoTerminateThread.Create(MainWindowHandle: THandle;
EndTime: TDateTime);
begin
inherited Create(False);
FreeOnTerminate := True;
FMainWndHandle := MainWindowHandle;
FTerminateTime := EndTime;
FWaitEvent := CreateEvent(nil, True, False, nil);
if FWaitEvent = 0 then
RaiseLastOSError;
end;
destructor TAutoTerminateThread.Destroy;
begin
CloseHandle(FWaitEvent);
inherited Destroy;
end;
procedure TAutoTerminateThread.Terminate;
begin
SetEvent(FWaitEvent);
inherited Terminate;
end;
procedure TAutoTerminateThread.Execute;
var
WaitTime: Cardinal;
begin
WaitTime := Trunc(FTerminateTime - Now) * 1000;
if WaitForSingleObject(FWaitEvent, WaitTime) = WAIT_TIMEOUT then
begin
{>> On n'a fait pas appel à Terminate et le temps s'est écoulé: on quitte }
{ D'abord, la méthode "douce" (pas SendMessage car si l'autre thread
est bloqué, celui-ci aussi va se bloquer) }
PostMessage(FMainWndHandle, WM_CLOSE, 0, 0);
{ On attend encore un peu pour voir si l'autre thread fait
appel à Terminate ou s'il est vraiment coincé (5 secondes maxi) }
if WaitForSingleObject(FWaitEvent, 5000) = WAIT_TIMEOUT then
begin
{ Coinçage total: suicide obligé ! }
Beep;
TerminateProcess(GetCurrentProcess, 1);
end;
end;
end;
procedure TFrmTest.FormCreate(Sender: TObject);
begin
{>> Le programme va se fermer 5 secondes après son ouverture }
FTermThread := TAutoTerminateThread.Create(Handle, Now + 5.0);
end;
procedure TFrmTest.FormDestroy(Sender: TObject);
begin
{>> On signale au thread de se terminer: la procédure WaitForSingleObject
renvoit immédiatement WAIT_OBJECT_0 et le thread se détruit normelement }
FTermThread.Terminate;
end;
procedure TFrmTest.BtnQuitClick(Sender: TObject);
begin
Close;
end;
procedure TFrmTest.BtnPlanteClick(Sender: TObject);
begin
while True do
Sleep(10);
end;
end.
Alors, qu'en pensez-vous ?
|
|
|
Cette discussion est classé dans : application, question, heure, thread, threads
Répondre à ce message
Sujets en rapport avec ce message
Question bête sur les threads ! [ par BKnet ]
Bonjour tout le monde, J'aimerai savoir si on peut associer un évènement sur un thread ? Si oui comment ? Si non y a t'il une autre solution ? Dans
Threads et events [ par Danonne ]
Salut a tous.Après de nombreuses recherches sur divers sites et forums, je n'ai pas réussi à trouver une réponse (claire et précise) à ma question exi
Utilisation de Threads : Bien ou pas bien ? [ par Francky23012301 ]
Salut à tous,Une petite question (Oui encore ) : Je suis entrain de faire un ptit truc . Je met un screenshot ca sera plus rapide que d'expliquer la
threads [ par sisi231 ]
SISI231Je me suis mis aux threads y'a 2 jours : j'ai un peu compris , j'ai corrigé une erreur grace à synchronize mais il en reste une : (petite expli
Mise à jour de la l'heure [ par josserand ]
Bonjour !Je souhaite affiché la date et l'heure sur l'interface de mon application.Problème, elle ne s'initialise qu'au démarrage de l'application.J'a
simple question [ par jeckman ]
je cherche a faire a faire un logiciel en DELPHI ! Mais je ne voit pas comment m'y prendre pour faire ça ! Je vais vous expliquer ! Je travaille a
OpenGL et Threads [ par FleX2009 ]
Bonjour à tous, voilà j'ai un petit problème : je veux dessiner en OpenGL dans un thread, mon algo est du type : Boucle Dessin Fin boucle // jusque i
Un ptite question ;-). [ par Becracker ]
Salut les gars, Je voudrais savoir que veux dire le message suivant : [Avertissement] Main.pas(119): Le symbole 'FindData' est propre à une platefor
Une question pour les pros de delphi ? [ par Fredelphi ]
Bonjour,Est-il possible d'influencer une variable ou un controle d'une application à partir d'une autre application ??Je m'explique : Je lance le prog
Comment dialoguer entre deux threads [ par nicolaspennaneach ]
Voilà, j'ai deux threads. Un gère les entrées claviers et l'autre gère la connection à une machine distante en telnet.Ce que je souhaiterai savoir c'e
Livres en rapport
|
Téléchargements
Logiciels à télécharger sur le même thème :
|