[Résolu] Pause qui libère le CPU?

Pause qui libère le CPU? [Résolu] - Delphi/Pascal - Programmation

Marsh Posté le 03-11-2006 à 20:35:35    

Salut à tous
 
y a déja un topic qui parle des pauses mais c'est différent
 
voila j'ai fait une procédure qui utilise Application.ProcessMessages; pour faire une pause avec un temps variable (de une minute voir moins à plus de deux heures) le problème c'est que ça utilise 50% du CPU sur un A64 X2 c'est ennuyeux...le but est que l'appli puisse tourner en tache de fond et meme sur un 'petit' PC genre Pentium 200Mhz
 
 


debut procedure.............
.....      
      Top := now;
      stop:=false ;
      repeat
      if (now < top+((wait)/1000/3600/24)) then
      begin
      Application.ProcessMessages;
      if Button4.caption='Auto' then stop:=true;
      end
      until  (now = top+((wait)/1000/3600/24)) or stop;
end;
;


 
wait est en milisecondes, meme en retirant "if Button4.caption='Auto' then stop:=true;" (si y a pas ça c'est ctrl+alt+suppr pour sortir...)ça pompe du CPU au taquet!
 
je sais pas si ce genre de procédure est fait pour pas durer longtemps ou quoi, j'ai vu un tuto sur les threads mais ça me fait un peu peur : http://reisubar.developpez.com/threadevents/ y a pas un moyen de faire plus simple?


Message édité par Flagad'aware le 07-11-2006 à 00:24:36
Reply

Marsh Posté le 03-11-2006 à 20:35:35   

Reply

Marsh Posté le 03-11-2006 à 20:56:24    

Citation :

y a pas un moyen de faire plus simple?


 
euh ... non ^^

Reply

Marsh Posté le 03-11-2006 à 23:23:18    

Application.HandleMessage
 
Mais tant que l'application ne reçoit plus de messages, elle risque de ne pas repasser dans la boucle, donc c'est plutôt une solution quand on attend un évément de la part de l'utilisateur.
 
Sinon pourquoi n'utilises-tu pas Sleep ? Faire des pauses de quelques secondes (ou millisecondes si l'application doit réagir tout de suite) via Sleep allègera pas mal le CPU.
Voire même faire juste un Sleep de la durée requise, mais pendant le temps du Sleep l'application est bloquée.
 
Encore une autre solution : utiliser un TTimer, qui déclanche un événement après un nombre de secondes prédéfíni.


Message édité par antp le 03-11-2006 à 23:24:47

---------------
mes programmes ·· les voitures dans les films ·· apprenez à écrire
Reply

Marsh Posté le 04-11-2006 à 00:05:23    

oua faut faire un choix   :cry:  
 
oui je connaissait sleep mais effectivement ça bloque un peu à la bourrin et comme c'est une appli où on peut faire pas mal de trucs (alors que cette boucle est en cours) ça serait dommage, c'est toujours bien mieux quand elle est réactive :), au pire y a moyen d'utiliser les deux
 
je vais chercher du coté du TTimer, Application.HandleMessage risque de bugger car l'utilisateur utilisera prèsque toujours que cette boucle
 
Merci Antp  :)

Reply

Marsh Posté le 04-11-2006 à 00:48:53    

Flagad'aware a écrit :

Application.HandleMessage risque de bugger car l'utilisateur utilisera prèsque toujours que cette boucle


:??: le seul risque avec HandleMessage c'est si l'application est réduite ou en arrière-plan (et encore, c'est à tester)


Message édité par antp le 04-11-2006 à 00:49:13

---------------
mes programmes ·· les voitures dans les films ·· apprenez à écrire
Reply

Marsh Posté le 05-11-2006 à 02:21:52    

excuses-moi si je me suis mal exprimé mais justement c'est ça principale fonction de l'appli donc si bug pas bon c'est pour ça que je me suis permis de douter sans essayer  :ange:
 
dans l'utilisation la plus courante, l'utilisateur ne fait rien d'autre qu'activer+arrière plan c'est pour ça  :)

Reply

Marsh Posté le 05-11-2006 à 13:38:28    

Pourquoi ne veut-tu pas regarder du coté des Thread :) ?
 
en Delphi c'est extremement simple et cela répond a ton besoin

Reply

Marsh Posté le 05-11-2006 à 20:21:41    

bah ça me parrait plus simple comme ça :/, finalement avec HandleMessage ça a tourné plus de 5 heures avec l'appli minimisée dans la barre des taches et y en a eu des pauses. :)  
 
faudrait oui que je me penche sur les threads, parceque ce que je fait c'est assez bourrin et effectivement les threads seraient bien plus appropriés, la procédure que j'ai mis plus haut fait déja partie d'une boucle qui tourne tant que la caption d'un bouton est à manuel, le clic sur bouton fait passer de auto à manuel et inversement   [:barthaliastoxik]  

Reply

Marsh Posté le 05-11-2006 à 22:45:30    

Sinon le TTimer ça devrait être une bonne solution, c'est juste que tu dois penser ton code autrement (vu que t'as pas une boucle mais un événement).


---------------
mes programmes ·· les voitures dans les films ·· apprenez à écrire
Reply

Marsh Posté le 06-11-2006 à 23:14:47    

oui je crois que je vais déja essayer ça, en fait, y a pas grand chose à changer du point de vue boucle/evenement, y a surtout à "deboucler" (si si c'est comme ça qu'on dit  :D ) et le TTimer (re)lançera l'evenement avec le temps d'attente fixé par cette meme procedure, enfin je vois ça comme ça sans avoir essayé :whistle:  
 
par contre j'èspère qu'on peut facilement couper le timer?
 
 
mais galère les threads j'arrivai à rien déclarer
 
encore merci  :)
 
Edit: ça marche nickel! et le CPU peut s'envoyer un Pulco dans son Hamac  :D
 
je met ça si ça peut aider d'autre personnes dans mon cas, ça permet d'activer/désactiver le TTimer en cliquant sur un meme bouton:
 
 

procedure TMainForm.Button4Click(Sender: TObject);
begin
 if Button4.caption='Manuel' then // si "thread" déja auto on coupe le timer
  begin
  Button4.caption:='Auto';
  Timer.free;
  end
  else
  if Button4.caption='Auto' then // si "thread" manuel ou pas actif on lance le timer
   begin
    Button4.caption:='Manuel';
    Timer.Enabled:=True;
   end;
end;


 
et le code périodiquement lancé dans:
 
procedure TMainForm.TimerTimer(Sender: TObject);
 
(evenement OnTimer)


Message édité par Flagad'aware le 07-11-2006 à 00:07:09
Reply

Marsh Posté le 06-11-2006 à 23:14:47   

Reply

Marsh Posté le 07-11-2006 à 00:17:12    

le seul truc c'est qu'il faut toujours que l'interval soit assez grand pour lancer la procedure complète (TimerTimer) et au premier lancement il faut attendre que le temps de cet interval soit écoulé avant que ça décole


Message édité par Flagad'aware le 07-11-2006 à 00:19:09
Reply

Marsh Posté le 07-11-2006 à 11:38:10    

Ton Timer.Free me semble bizarre [:figti] C'est pas plutôt Enabled := False que t'aurais dû mettre ? :o Et ton test est fait à l'envers on dirait (les commentaires collent pas avec le code :??:)
Au passage, la comparaison sur le Caption du bouton c'est bien crado comme code :p j'aurais mis ça :

Code :
  1. Timer.Enabled := not Timer.Enabled;
  2. if Timer.Enabled then
  3.   Button4.Caption := 'Manuel'
  4. else
  5.   Button4.Caption := 'Auto';


Tu peux toujours désactiver le Timer dans le début du OnTimer (TimerTimer), et le réactiver à la fin.  
Pour le début, tu peux manuellement appeler la procédure TimerTimer dans le code.


Message édité par antp le 07-11-2006 à 11:40:08

---------------
mes programmes ·· les voitures dans les films ·· apprenez à écrire
Reply

Marsh Posté le 07-11-2006 à 20:08:08    

lol oui j'ai une facheuse tendance à coder comme un goret [:barthaliastoxik]  
 
j'ai déja vu un code comme Timer.Enabled := not Timer.Enabled; dans le TComport (connect /deconnect) mais j'avait pas capté comment ça marchait exactement alors j'ai zappé, voila seulement que je comprend qu'en fait on applique à l'état du timer l'inverse de cet état qu'il soit actif ou pas :/
 
 
par contre non c'est pas inversé par rapport au commentaire enfin plutôt il est pas très clair... mais, pour l'appli, si la caption est à Manuel ça veut dire que la boucle est lancée et inversement  :whistle: , j'aurais du peut être commencer par if Button4.caption='Auto' then mais c'était pour couper la boucle que manuel était avant(heu si je me souviens bien)  
 
effectivement pour Timer.Enabled := False ça permetra surement de pas planter avec "access violation" au bout de trois clics sur le bouton4  lol quoique le timer s'arrète bien


Message édité par Flagad'aware le 07-11-2006 à 20:10:11
Reply

Marsh Posté le 07-11-2006 à 20:42:46    

Évidemment qu'il s'arrête puisque tu le détruis [:kiki] Mais pour le remettre en route il va avoir du mal (ou alors ça va fonctionner très aléatoirement tant que la zone mémoire n'est pas réutilisée par autre chose...)
 
machin := not machin
ça veut dire que tu inverses son état. Comme un interrupteur quoi.
Puis ensuite tu mets à jour le caption en fonction du nouvel état.


Message édité par antp le 07-11-2006 à 20:43:23

---------------
mes programmes ·· les voitures dans les films ·· apprenez à écrire
Reply

Marsh Posté le 07-11-2006 à 20:59:30    

ok lol, c'est pour ça que ça plantait en le réactivant...
 
par contre j'arrive pas à lancer manuellement TimerTimer  :??:  
 
finalement j'ai fait ça:
 

Code :
  1. procedure TMainForm.Button4Click(Sender: TObject);
  2. begin
  3. // Timer.Enabled:= not Timer.Enabled;
  4. if Timer.Enabled=true then
  5.   begin
  6.    Timer.Enabled:=false;
  7.    Button4.Caption := 'Auto';
  8.    Button1.enabled:=true;
  9.   end
  10.   else
  11.   begin
  12.    Button4.caption:='Manuel';
  13.    Button1.enabled:=false;
  14.    TimerTimer;// il me met pas assez de param. originaux
  15.   end;
  16. end;


 
et j'active le timer à la fin de TimerTimer juste après avoir paramétré l'interval
 
en fait j'ai jamais trouvé comment faire pour lancer manuellement, à chaque fois ça m'oblige à créer une procédure distincte et à l'appeler dans un buttonClick ou autre...
 
excuses-moi de te faire perdre ton temps avec mes questions de newbie

Reply

Marsh Posté le 07-11-2006 à 21:34:50    

ouff j'ai trouvé...
 
TimerTimer(Mainform);

Reply

Marsh Posté le 08-11-2006 à 09:47:30    

ou TimerTimer(Timer) pour faire comme si c'est le Timer qui l'avait déclanché (le paramètre c'est ce que tu reçois comme variable "Sender" pour savoir qui a appelé la procédure au cas où plusieurs composants sont reliés à la même procédure). Dans ton cas ça ne changera rien ;)


---------------
mes programmes ·· les voitures dans les films ·· apprenez à écrire
Reply

Marsh Posté le 08-11-2006 à 19:36:54    

ok je comprend mieux.
 
c pô toujours evident surtout quand on apprend comme ça à partir de prèsque rien, suis à la FAQ moi pas à la FAC   [:athlonxp2100+]  
 
tourne nickel maintenant mon appli  [:gijar]  
 
Merci beaucoup pour ton aide  :hello:

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed