Charge CPU

junior31490 Messages postés 24 Date d'inscription vendredi 28 juillet 2006 Statut Membre Dernière intervention 15 avril 2008 - 7 nov. 2007 à 11:29
junior31490 Messages postés 24 Date d'inscription vendredi 28 juillet 2006 Statut Membre Dernière intervention 15 avril 2008 - 8 nov. 2007 à 12:03
Bonjour
J'ai un problème, on m'a demandé de créer une petite apllication console permettant d'afficher la charge CPU d'un processus donné en fonction de son PID.
Pour cela, j'ai écris un petit bout de code, mais il me renvoit des valeurs totalement incohérente.

  // Declaration variables
  HANDLE hProcess;  
  FILETIME createTime;
  FILETIME exitTime;
  FILETIME kernelTime;
  FILETIME userTime; 
  SYSTEMTIME st;  
  int bStatus; 
  int pid = 2896;//PID du processus désiré
  
  long div1;
  long div2;
  long div;
  long test;
  long test1;
  long test2;
  long test3;
  while(1)
  {
   
         hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid);
         bStatus = GetProcessTimes(hProcess, &createTime, &exitTime, &kernelTime, &userTime);
         if (bStatus)
         {
                FileTimeToSystemTime(&kernelTime, &st);
                test1 = st.wHour*60 + st.wMinute*60 + st.wSecond*60 + st.wMilliseconds*1000;
                FileTimeToSystemTime(&userTime, &st);
                test2 = st.wHour*60 + st.wMinute*60 + st.wSecond*60 + st.wMilliseconds*1000;
                FileTimeToSystemTime(&createTime, &st);
                test3 = st.wHour*60 + st.wMinute*60 + st.wSecond*60 + st.wMilliseconds*1000;
                GetLocalTime(&st);
                test = st.wHour*60 + st.wMinute*60 + st.wSecond*60 + st.wMilliseconds*1000;
                system("cls");
                div1=(test1 + test2)*100;
                div2=(10 * (test - test3));
                div = div1/div2;
                printf ("%ld\n", div);
                Sleep(1000);    
         }
         CloseHandle(hProcess);   
  }

Est ce que quelqu'un voit où est le pb?

Merci d'avance...

17 réponses

luhtor Messages postés 2023 Date d'inscription mardi 24 septembre 2002 Statut Membre Dernière intervention 28 juillet 2008 6
7 nov. 2007 à 13:05
test1 = st.wHour*60 + st.wMinute*60 + st.wSecond*60 + st.wMilliseconds*1000;

=> Il est censé faire quoi ce calcul ?
0
junior31490 Messages postés 24 Date d'inscription vendredi 28 juillet 2006 Statut Membre Dernière intervention 15 avril 2008
7 nov. 2007 à 13:12
En faite, j'ai fait ce calcul car je ne sais pas comment transformé FILETIME en type que je puisse exploiter simplement.
Je connais la solution:
typedef unsigned long long int uint64;
GetProcessTimes(hProcess, &createTime, &exitTime, &kernelTime, &userTime);
uint64 lKernel = (kernelTime.dwHighDateTime << 32) | (kernelTime.dwLowDateTime);
uint64 lUser = (userTime.dwHighDateTime << 32) | (userTime.dwLowDateTime);
uint64 lCreate = (createTime.dwHighDateTime << 32) | (createTime.dwLowDateTime);
SYSTEMTIME lCurrentSystemTime;
FILETIME lCurrentFileTime;
GetSystemTime(&lCurrentSystemTime);
SystemTimeToFileTime(&lCurrentSystemTime, &lCurrentFileTime);
float lCpu = (lKernel + lUser) / (10 * (lCurrentFileTime - lCreate));

Mais elle ne marche pas. Donc j'ai essayé de transformer un temps en entier (mais à priori ce n'est pas bon).

Tu vois comment je peux faire?
0
junior31490 Messages postés 24 Date d'inscription vendredi 28 juillet 2006 Statut Membre Dernière intervention 15 avril 2008
7 nov. 2007 à 15:39
Svp, aidez-moi!!!!!!
0
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
7 nov. 2007 à 18:55
Cherche NtQuerySystemInformation() sur le web, vaste sujet.

ciao...
BruNews, MVP VC++
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
luhtor Messages postés 2023 Date d'inscription mardi 24 septembre 2002 Statut Membre Dernière intervention 28 juillet 2008 6
7 nov. 2007 à 23:48
Dans la version que je t'avais donné, il y avait quelques erreurs, qu'il aurait fallu que tu corriges ...

FILETIME createTime, exitTime, kernelTime, userTime;
  
typedef unsigned long long int uint64;

GetProcessTimes(GetCurrentProcess(), &createTime, &exitTime, &kernelTime, &userTime);
uint64 lKernel = (uint64(kernelTime.dwHighDateTime) << 32) | (kernelTime.dwLowDateTime);
uint64 lUser = (uint64(userTime.dwHighDateTime) << 32) | (userTime.dwLowDateTime);
uint64 lCreate = (uint64(createTime.dwHighDateTime) << 32) | (createTime.dwLowDateTime);

SYSTEMTIME lCurrentSystemTime;
FILETIME lCurrentFileTime;
GetSystemTime(&lCurrentSystemTime);
SystemTimeToFileTime(&lCurrentSystemTime, &lCurrentFileTime);

uint64 lCurrent = (uint64(lCurrentFileTime.dwHighDateTime) << 32) | (lCurrentFileTime.dwLowDateTime);
double lCpu = double(lKernel + lUser) / double(lCurrent - lCreate);

Mais ca, ca fait la moyenne depuis que le processus est lancé. Pour bien faire, il faudrait faire la moyenne sur une seconde.
0
junior31490 Messages postés 24 Date d'inscription vendredi 28 juillet 2006 Statut Membre Dernière intervention 15 avril 2008
8 nov. 2007 à 09:00
Il ne me prend pas cette ligne : "typedef unsigned long long int uint64;"
Il me dit: "error C2632: 'long' followed by 'long' is illegal"
Je pense que c'est parce que je n'ai pas de librairie 64 bits.
Tu vois comment je pourrais faire?
0
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
8 nov. 2007 à 09:36
sur VC++:
unsigned __int64

ciao...
BruNews, MVP VC++
0
junior31490 Messages postés 24 Date d'inscription vendredi 28 juillet 2006 Statut Membre Dernière intervention 15 avril 2008
8 nov. 2007 à 10:13
Voila exactement ce que j'ai marqué:
  // Declaration variables
  HANDLE hProcess;  
  int bStatus;
  int pid = 6140;

  while(1)
  {   
         hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid);
         bStatus = GetProcessTimes(hProcess, &createTime, &exitTime, &kernelTime, &userTime);
         if (bStatus)
         {
               FILETIME createTime, exitTime, kernelTime, userTime;
               uint64 lKernel = (uint64(kernelTime.dwHighDateTime) << 32) | (kernelTime.dwLowDateTime);
               uint64 lUser = (uint64(userTime.dwHighDateTime) << 32) | (userTime.dwLowDateTime);
               uint64 lCreate = (uint64(createTime.dwHighDateTime) << 32) | (createTime.dwLowDateTime);
    
                SYSTEMTIME lCurrentSystemTime;
                FILETIME lCurrentFileTime;
                GetSystemTime(&lCurrentSystemTime);
                SystemTimeToFileTime(&lCurrentSystemTime, &lCurrentFileTime);
    
                uint64 lCurrent = (uint64(lCurrentFileTime.dwHighDateTime) << 32) | (lCurrentFileTime.dwLowDateTime);
                double lCpu = double(kernelTime.dwLowDateTime + userTime.dwLowDateTime) / double(lCurrentFileTime.dwLowDateTime - createTime.dwLowDateTime);


                system("cls");
                printf("%ld\n", lCpu);
                Sleep(100);
         }
         CloseHandle(hProcess);   
  }
Est ce que vous voyez une incohérence?
Ce code compile mais marque vraiment n'importe quoi, même des choses négatives alors que c'est un unsigned.
Merci de m'aider
0
junior31490 Messages postés 24 Date d'inscription vendredi 28 juillet 2006 Statut Membre Dernière intervention 15 avril 2008
8 nov. 2007 à 10:17
si je met ce ue m'a donné luhtor pour le calcul du pourcentage(cad : "double lCpu double(lKernel + lUser) / double(lCurrent - lCreate);" à la place de "double lCpu double(kernelTime.dwLowDateTime + userTime.dwLowDateTime) / double(lCurrentFileTime.dwLowDateTime - createTime.dwLowDateTime);") le compilateur me dit : "error C2520: conversion from unsigned __int64 to double not implemented, use signed __int64" comment puis-je éviter ce pb?
0
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
8 nov. 2007 à 10:27
mets un cast devant (__int64)

ciao...
BruNews, MVP VC++
0
luhtor Messages postés 2023 Date d'inscription mardi 24 septembre 2002 Statut Membre Dernière intervention 28 juillet 2008 6
8 nov. 2007 à 11:29
"printf("%Lf\n", lCpu);" <= ca sera deja mieux...

Si tu as tjs le message d'erreur. Tu n'as qu'a faire ce que te dis le message d'erreur, tu remplaces les uint64 par __int64.
0
junior31490 Messages postés 24 Date d'inscription vendredi 28 juillet 2006 Statut Membre Dernière intervention 15 avril 2008
8 nov. 2007 à 11:52
ahhhhhhhhhhhhhhhhhhhhhh
ça ne marche tjrs pas
maintenant ça compile nickel, mais ça m'affiche tjrs la même valeur (négative) -1.932740 et pour n'importe quel processus.

si quelqu'un a une idée du pk du comment, je suis preneur...
0
luhtor Messages postés 2023 Date d'inscription mardi 24 septembre 2002 Statut Membre Dernière intervention 28 juillet 2008 6
8 nov. 2007 à 11:52
Bon je plaquarde la fonction fonctionnelle qui calcul la charge instantanée. C'est compilé sous devcpp, j'avais la flemme de créer un projet sous VC. Donc adapte le a VC en remplacant les types:

#include <windows.h>
#include <stdio.h>

int main(int argc, char * argv[])
{
  HANDLE hProcess; 
  int bStatus;
  int pid = 3800;
 
  FILETIME createTime, exitTime, kernelTime, userTime;
 
  typedef unsigned long long int uint64;
    uint64 lOldKernel 0, lOldUser 0, lOldCreate = 0, lOldCurrent = 0;

  while(1)
  {  
         hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid);
         bStatus = GetProcessTimes(hProcess, &createTime, &exitTime, &kernelTime, &userTime);
         if (bStatus)
         {
               uint64 lKernel = (uint64(kernelTime.dwHighDateTime) << 32) | uint64(kernelTime.dwLowDateTime);
               uint64 lUser = (uint64(userTime.dwHighDateTime) << 32) | uint64(userTime.dwLowDateTime);
               uint64 lCreate = (uint64(createTime.dwHighDateTime) << 32) | uint64(createTime.dwLowDateTime);
   
                SYSTEMTIME lCurrentSystemTime;
                FILETIME lCurrentFileTime;
                GetSystemTime(&lCurrentSystemTime);
                SystemTimeToFileTime(&lCurrentSystemTime, &lCurrentFileTime);
   
                uint64 lCurrent = (uint64(lCurrentFileTime.dwHighDateTime) << 32) | uint64(lCurrentFileTime.dwLowDateTime);

                double lCpu = 100.0 * double(lKernel - lOldKernel + lUser - lOldUser) / double(lCurrent - lOldCurrent);

                lOldKernel = lKernel;
                lOldUser = lUser;
                lOldCreate = lCreate;
                lOldCurrent = lCurrent;

                if (lOldCurrent != 0)
                    printf("%Lf %%\n", lCpu);
                   
                Sleep(1000);
         }
  }
 
  system("PAUSE");
 
  return 0;
}
0
luhtor Messages postés 2023 Date d'inscription mardi 24 septembre 2002 Statut Membre Dernière intervention 28 juillet 2008 6
8 nov. 2007 à 11:54
Il manque un petit test de nullité sur le dénominateur: double(lCurrent - lOldCurrent).
Enfin normalement avec le Sleep(1000) il ne devrait pas y avoir de problèmes.
0
luhtor Messages postés 2023 Date d'inscription mardi 24 septembre 2002 Statut Membre Dernière intervention 28 juillet 2008 6
8 nov. 2007 à 11:57
Oups, j'ai aussi enlevé le CloseHandle qu'il faut rajouter, et bien sur j'ai modifié le pid, donc adapte le.
0
junior31490 Messages postés 24 Date d'inscription vendredi 28 juillet 2006 Statut Membre Dernière intervention 15 avril 2008
8 nov. 2007 à 12:02
luhtor je t'aimeeeeeeeeeeeeee
tu es un boss...
ça marche nickel
1000 merci...
0
junior31490 Messages postés 24 Date d'inscription vendredi 28 juillet 2006 Statut Membre Dernière intervention 15 avril 2008
8 nov. 2007 à 12:03
merci aussi à BruNews pour son aide
0
Rejoignez-nous