IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

API, COM et SDKs Delphi Discussion :

[D6] Processus - temps processeur


Sujet :

API, COM et SDKs Delphi

  1. #21
    Expert éminent
    Avatar de Lung
    Profil pro
    Analyste-programmeur
    Inscrit en
    Mai 2002
    Messages
    2 664
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste-programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 664
    Points : 6 967
    Points
    6 967
    Par défaut
    Bon, j'ai déporté les conversions après les mesures.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    var
       hProcessHandle: THandle;
       lii: tagLASTINPUTINFO;
       nIdle1, nKernelTime1, nUserTime1, nIdle2, nKernelTime2, nUserTime2: Int64;
       lpCreationTime, lpExitTime, lpKernelTime1, lpUserTime1, lpKernelTime2, lpUserTime2: _FILETIME;      // TFileTime
       lpsKernelTime, lpsUserTime: _SYSTEMTIME;
       dDeltaIdle, dDeltaKernelUser: Double;
    begin
       hProcessHandle := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, False, ProcessEntry.th32ProcessID);
       try
          //.Première mesure.
          lii.cbSize := SizeOf(tagLASTINPUTINFO);
          if not GetLastInputInfo(lii) then
             Exit;
          nIdle1 := lii.dwTime;
     
          if not GetProcessTimes(hProcessHandle, lpCreationTime, lpExitTime, lpKernelTime1, lpUserTime1) then
          begin
             Application.MessageBox(PChar('GetProcessTimes 1' + #13#10 + SysErrorMessage(GetLastError)), PChar(Caption + ' - erreur'), MB_ICONERROR + MB_OK);
             Exit;
          end;
     
          //.Pause.
          Sleep(500);
     
          //.Deuxième mesure.
          if not GetLastInputInfo(lii) then
             Exit;
          nIdle2 := lii.dwTime;
     
          if not GetProcessTimes(hProcessHandle, lpCreationTime, lpExitTime, lpKernelTime2, lpUserTime2) then
          begin
             Application.MessageBox(PChar('GetProcessTimes 2' + #13#10 + SysErrorMessage(GetLastError)), PChar(Caption + ' - erreur'), MB_ICONERROR + MB_OK);
             Exit;
          end;
     
          //.Conversions.
          if not FileTimeToSystemTime(lpKernelTime1, lpsKernelTime) then
             Exit;
          nKernelTime1 := (lpsKernelTime.wHour * 60 * 60 * 1000) + (lpsKernelTime.wMinute * 60 * 1000) + (lpsKernelTime.wSecond * 1000) + lpsKernelTime.wMilliseconds;
          if not FileTimeToSystemTime(lpUserTime1, lpsUserTime) then
             Exit;
          nUserTime1 := (lpsUserTime.wHour * 60 * 60 * 1000) + (lpsUserTime.wMinute * 60 * 1000) + (lpsUserTime.wSecond * 1000) + lpsUserTime.wMilliseconds;
     
          if not FileTimeToSystemTime(lpKernelTime2, lpsKernelTime) then
             Exit;
          nKernelTime2 := (lpsKernelTime.wHour * 60 * 60 * 1000) + (lpsKernelTime.wMinute * 60 * 1000) + (lpsKernelTime.wSecond * 1000) + lpsKernelTime.wMilliseconds;
          if not FileTimeToSystemTime(lpUserTime2, lpsUserTime) then
             Exit;
          nUserTime2 := (lpsUserTime.wHour * 60 * 60 * 1000) + (lpsUserTime.wMinute * 60 * 1000) + (lpsUserTime.wSecond * 1000) + lpsUserTime.wMilliseconds;
     
          //.Calculs (NdisGetCurrentProcessorCounts [ CpuUsage = 100-100*(Idle - Idle[n])/(KernelAndUser - KernelAndUser[n]) ]).
          dDeltaIdle := (nIdle2 - nIdle1);
          dDeltaKernelUser := (nKernelTime2 + nUserTime2) - (nKernelTime1 + nUserTime1);
          if dDeltaKernelUser = 0 then
             dTempsProcesseur := 0
          else
          begin
             dTempsProcesseur := dDeltaIdle / dDeltaKernelUser;
             dTempsProcesseur := 100 - 100 * _dTempsProcesseur;
          end;
       finally
          CloseHandle(hProcessHandle);
       end;
    Citation Envoyé par Mac LAK Voir le message
    A des fins de debug, tu devrais afficher toutes les valeurs intermédiaires avant (et après) avoir fait les calculs, de façon à voir "à l'œil" les mesures étranges.
    C'est ce que j'avais commencé à faire.

    Citation Envoyé par Mac LAK Voir le message
    il faudra que tu le fasses et que tu mettes les résultats ici pour pouvoir t'aider au diagnostic.
    Voici le détail quand j'obtiens 100 (par exemple):
    ### MESURE 1 :
    lpsKernelTime.wHour : 0 [0 * 60 * 60 * 1000 = 0]
    lpsKernelTime.wMinute : 0 [0 * 60 * 1000 = 0]
    lpsKernelTime.wSecond : 4 [4 * 1000 = 32000]
    lpsKernelTime.wMilliseconds : 15
    (0 * 60 * 60 * 1000) + (0 * 60 * 1000) + (4 * 1000) + 15 = 4015

    lpsUserTime.wHour : 0 [0 * 60 * 60 * 1000 = 0]
    lpsUserTime.wMinute : 0 [0 * 60 * 1000 = 0]
    lpsUserTime.wSecond : 32 [32 * 1000 = 32000]
    lpsUserTime.wMilliseconds : 265
    (0 * 60 * 60 * 1000) + (0 * 60 * 1000) + (32 * 1000) + 265 = 32265

    ### MESURE 2 :
    lpsKernelTime.wHour : 0 [0 * 60 * 60 * 1000 = 0]
    lpsKernelTime.wMinute : 0 [0 * 60 * 1000 = 0]
    lpsKernelTime.wSecond : 4 [4 * 1000 = 32000]
    lpsKernelTime.wMilliseconds : 31
    (0 * 60 * 60 * 1000) + (0 * 60 * 1000) + (4 * 1000) + 31 = 4031

    lpsUserTime.wHour : 0 [0 * 60 * 60 * 1000 = 0]
    lpsUserTime.wMinute : 0 [0 * 60 * 1000 = 0]
    lpsUserTime.wSecond : 32 [32 * 1000 = 32000]
    lpsUserTime.wMilliseconds : 296
    (0 * 60 * 60 * 1000) + (0 * 60 * 1000) + (32 * 1000) + 296 = 32296

    ### CALCULS :
    nIdle1 : 140328
    nIdle2 : 140328
    nKernelTime1 : 4015
    nUserTime1 : 32265
    nKernelTime2 : 4031
    nUserTime2 : 32296
    dDeltaIdle = 0
    dDeltaKernelUser = 47
    Et voici quand j'obtiens 0 :
    ### MESURE 1 :
    lpsKernelTime.wHour : 0 [0 * 60 * 60 * 1000 = 0]
    lpsKernelTime.wMinute : 0 [0 * 60 * 1000 = 0]
    lpsKernelTime.wSecond : 3 [3 * 1000 = 31000]
    lpsKernelTime.wMilliseconds : 953
    (0 * 60 * 60 * 1000) + (0 * 60 * 1000) + (3 * 1000) + 953 = 3953

    lpsUserTime.wHour : 0 [0 * 60 * 60 * 1000 = 0]
    lpsUserTime.wMinute : 0 [0 * 60 * 1000 = 0]
    lpsUserTime.wSecond : 31 [31 * 1000 = 31000]
    lpsUserTime.wMilliseconds : 531
    (0 * 60 * 60 * 1000) + (0 * 60 * 1000) + (31 * 1000) + 531 = 31531

    ### MESURE 2 :
    lpsKernelTime.wHour : 0 [0 * 60 * 60 * 1000 = 0]
    lpsKernelTime.wMinute : 0 [0 * 60 * 1000 = 0]
    lpsKernelTime.wSecond : 3 [3 * 1000 = 31000]
    lpsKernelTime.wMilliseconds : 953
    (0 * 60 * 60 * 1000) + (0 * 60 * 1000) + (3 * 1000) + 953 = 3953

    lpsUserTime.wHour : 0 [0 * 60 * 60 * 1000 = 0]
    lpsUserTime.wMinute : 0 [0 * 60 * 1000 = 0]
    lpsUserTime.wSecond : 31 [31 * 1000 = 31000]
    lpsUserTime.wMilliseconds : 531
    (0 * 60 * 60 * 1000) + (0 * 60 * 1000) + (31 * 1000) + 531 = 31531

    ### CALCULS :
    nIdle1 : 126781
    nIdle2 : 126781
    nKernelTime1 : 3953
    nUserTime1 : 31531
    nKernelTime2 : 3953
    nUserTime2 : 31531
    dDeltaIdle = 0
    dDeltaKernelUser = 0
    Citation Envoyé par Mac LAK Voir le message
    Mais dans tous les cas, ne trouver QUE 0 ou 100 comme valeurs, c'est anormal et cela sous-entends que tu as des mesures non-fiables, du genre "détecter si je suis au dessus ou en dessous des 50% d'occupation"...
    Quand je regarde le détail, j'ai des valeurs bizarres qui semblent disparaitre quand je fais le calcul complet. Pourtant, un entier (logiquement) n'est pas sensé avoir de décimales cachées.
    L'urgent est fait, l'impossible est en cours, pour les miracles prévoir un délai. ___ Écrivez dans un français correct !!

    C++Builder 5 - Delphi 6#2 Entreprise - Delphi 2007 Entreprise - Delphi 2010 Architecte - Delphi XE Entreprise - Delphi XE7 Entreprise - Delphi 10 Entreprise - Delphi 10.3.2 Entreprise - Delphi 10.4.2 Entreprise - Delphi 11.1 Entreprise
    OpenGL 2.1 - Oracle 10g - Paradox - Interbase (XE) - PostgreSQL (15.4)

  2. #22
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Citation Envoyé par Lung Voir le message
    Quand je regarde le détail, j'ai des valeurs bizarres qui semblent disparaitre quand je fais le calcul complet. Pourtant, un entier (logiquement) n'est pas sensé avoir de décimales cachées.
    Le souci, c'est que tu as toujours un deltaIdle à zéro... Forcément, ça fausse les mesures.

    Il pourrait être intéressant, dans la boucle, de remplacer le Sleep par un code de ce genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    Repeat
      Sleep(1);
      Application.ProcessMessages();
      if not GetLastInputInfo(lii) then
         Exit;
      nIdle2 := lii.dwTime;
    Until (nIdle2<>nIdle1);
    Par contre, il faudra alors remplacer nIdle? dans les calculs par une mesure fiable (GetTickCount ou QPF) : en effet, j'avais mal lu la doc de GetLastInputInfo (enfin, de la structure passée en paramètre en fait).
    J'explique : cette fonction donne le tick de la dernière action utilisateur. Or, à priori, si tu ne fais RIEN, ce compteur ne peut pas varier !!
    Il faudrait donc threader ce calcul en tâche de fond (basse priorité), et conserver de façon publique le dernier taux d'occupation CPU trouvé par le thread. Ainsi, tu analyses la charge en temps réel, et tu regardes alors quelle est sa dernière valeur lorsque tu en as besoin.
    Pendant ce temps, tu continues de bosser, donc tu vas générer des évènements utilisateur, donc faire varier le résultat de GetLastInputInfo.

    Tiens-moi au courant.
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  3. #23
    Expert éminent
    Avatar de Lung
    Profil pro
    Analyste-programmeur
    Inscrit en
    Mai 2002
    Messages
    2 664
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste-programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 664
    Points : 6 967
    Points
    6 967
    Par défaut
    Citation Envoyé par Mac LAK Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    Repeat
      Sleep(1);
      Application.ProcessMessages();
      if not GetLastInputInfo(lii) then
         Exit;
      nIdle2 := lii.dwTime;
    Until (nIdle2<>nIdle1);
    Or, à priori, si tu ne fais RIEN, ce compteur ne peut pas varier !!
    Effectivement. Il faut bouger la souris pour que ça sorte de la boucle.
    Ca ne me convient pas. L'utilisateur n'est pas forcément devant son poste. Donc, personne ne bougera la souris.

    Citation Envoyé par Mac LAK Voir le message
    Il faudrait donc threader ce calcul en tâche de fond (basse priorité), et conserver de façon publique le dernier taux d'occupation CPU trouvé par le thread. Ainsi, tu analyses la charge en temps réel, et tu regardes alors quelle est sa dernière valeur lorsque tu en as besoin.
    Ca se complique, là !
    Je pensais pas que ça allait être si compliqué.
    En plus, le but c'était de gagner du temps. Or là, j'ai l'impression que le temps de prendre des mesures, va être non négligeable. En plus, il faut qu'il y ait une action utilisateur, ce qui n'est pas forcé.
    L'urgent est fait, l'impossible est en cours, pour les miracles prévoir un délai. ___ Écrivez dans un français correct !!

    C++Builder 5 - Delphi 6#2 Entreprise - Delphi 2007 Entreprise - Delphi 2010 Architecte - Delphi XE Entreprise - Delphi XE7 Entreprise - Delphi 10 Entreprise - Delphi 10.3.2 Entreprise - Delphi 10.4.2 Entreprise - Delphi 11.1 Entreprise
    OpenGL 2.1 - Oracle 10g - Paradox - Interbase (XE) - PostgreSQL (15.4)

  4. #24
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Tu n'as pas compris : il te faut virer GetLastInputInfo totalement, et le remplacer par un GetTickCount ou QPF, avec un Sleep pour endormir ton thread de mesure.

    Ce thread tourne en permanence, en basse priorité, et compare le temps réel écoulé (ex : 600 ms) par rapport au temps consommé par le processus surveillé pendant cette même période (ex : 342 ms).

    Tu en déduis alors une charge approximative, qu'il te suffit de mettre dans une variable globale qui ne sera écrite QUE par ton thread, et lue par le reste de ton application.
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  5. #25
    Expert éminent
    Avatar de Lung
    Profil pro
    Analyste-programmeur
    Inscrit en
    Mai 2002
    Messages
    2 664
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste-programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 664
    Points : 6 967
    Points
    6 967
    Par défaut
    Citation Envoyé par Mac LAK Voir le message
    Ce thread tourne en permanence, en basse priorité, et compare le temps réel écoulé (ex : 600 ms) par rapport au temps consommé par le processus surveillé pendant cette même période (ex : 342 ms).
    Donc, il faudrait que ce thread tourne avant l'application.
    Difficile, car tout ça se passe au démarrage du poste de l'utilisateur.
    Je creuse la question ...
    L'urgent est fait, l'impossible est en cours, pour les miracles prévoir un délai. ___ Écrivez dans un français correct !!

    C++Builder 5 - Delphi 6#2 Entreprise - Delphi 2007 Entreprise - Delphi 2010 Architecte - Delphi XE Entreprise - Delphi XE7 Entreprise - Delphi 10 Entreprise - Delphi 10.3.2 Entreprise - Delphi 10.4.2 Entreprise - Delphi 11.1 Entreprise
    OpenGL 2.1 - Oracle 10g - Paradox - Interbase (XE) - PostgreSQL (15.4)

  6. #26
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Si tu veux juste scanner un processus donné, tu peux tout simplement ne pas threader ça, et faire une attente d'environ 500 à 1000 ms, et vérifier le résultat.

    Mais il me semblait que tu voulais vérifier une application à partir d'une autre application, c'est pour cela que je te parlais d'un thread plutôt que d'une attente "active" comme le ferait un petit utilitaire en ligne de commande.
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

Discussions similaires

  1. [Batch] [Technique] Processus , Temps , Messages
    Par sokai dans le forum Scripts/Batch
    Réponses: 4
    Dernier message: 14/10/2009, 08h40
  2. Récuper le temps processeur d'un processus
    Par KRis dans le forum Langage
    Réponses: 1
    Dernier message: 15/01/2009, 04h33
  3. 4Dclient - Utilisation du temps processeur
    Par clem9 dans le forum 4D
    Réponses: 4
    Dernier message: 19/09/2008, 09h34
  4. [SOLARIS] Consommation processus temps reel
    Par droussa dans le forum Solaris
    Réponses: 2
    Dernier message: 26/06/2007, 18h46
  5. [C#] "Access is denied" pour récupérer le temps processeur
    Par xtream dans le forum Windows Forms
    Réponses: 1
    Dernier message: 22/06/2006, 01h02

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo