2010-07-27 41 views
6

Sono riuscito a implementare il codice su questo listing per ottenere un elenco di tutti i processi in esecuzione e dei relativi ID. Ciò di cui ho bisogno ora è di estrarre quanto tempo ogni processo utilizza la CPU.CPU utilizzata da Processo

Ho provato a fare riferimento ai tasti nel codice, ma quando provo a stampare 'Ticks of CPU Time' ottengo un valore zero per tutti i processi. Inoltre, anche se ottengo un valore non sono sicuro che "Ticks of CPU Time" sia esattamente quello che sto cercando.

struct vmspace *p_vmspace; /* Address space. */ 
struct sigacts *p_sigacts; /* Signal actions, state (PROC ONLY). */ 
int p_flag;   /* P_* flags. */ 
char p_stat;   /* S* process status. */ 
pid_t p_pid;   /* Process identifier. */ 
pid_t p_oppid;  /* Save parent pid during ptrace. XXX */ 
int p_dupfd;  /* Sideways return value from fdopen. XXX */ 
/* Mach related */ 
caddr_t user_stack; /* where user stack was allocated */ 
void *exit_thread; /* XXX Which thread is exiting? */ 
int  p_debugger;  /* allow to debug */ 
boolean_t sigwait; /* indication to suspend */ 
/* scheduling */ 
u_int p_estcpu; /* Time averaged value of p_cpticks. */ 
int p_cpticks; /* Ticks of cpu time. */ 
fixpt_t p_pctcpu; /* %cpu for this process during p_swtime */ 
void *p_wchan; /* Sleep address. */ 
char *p_wmesg; /* Reason for sleep. */ 
u_int p_swtime; /* Time swapped in or out. */ 
u_int p_slptime; /* Time since last blocked. */ 
struct itimerval p_realtimer; /* Alarm timer. */ 
struct timeval p_rtime; /* Real time. */ 
u_quad_t p_uticks;  /* Statclock hits in user mode. */ 
u_quad_t p_sticks;  /* Statclock hits in system mode. */ 
u_quad_t p_iticks;  /* Statclock hits processing intr. */ 
int p_traceflag;  /* Kernel trace points. */ 
struct vnode *p_tracep; /* Trace to vnode. */ 
int p_siglist;  /* DEPRECATED */ 
struct vnode *p_textvp; /* Vnode of executable. */ 
int p_holdcnt;  /* If non-zero, don't swap. */ 
sigset_t p_sigmask; /* DEPRECATED. */ 
sigset_t p_sigignore; /* Signals being ignored. */ 
sigset_t p_sigcatch; /* Signals being caught by user. */ 
u_char p_priority; /* Process priority. */ 
u_char p_usrpri; /* User-priority based on p_cpu and p_nice. */ 
char p_nice;  /* Process "nice" value. */ 
char p_comm[MAXCOMLEN+1]; 
struct pgrp *p_pgrp; /* Pointer to process group. */ 
struct user *p_addr; /* Kernel virtual addr of u-area (PROC ONLY). */ 
u_short p_xstat; /* Exit status for wait; also stop signal. */ 
u_short p_acflag; /* Accounting flags. */ 
struct rusage *p_ru; /* Exit information. XXX */ 

In realtà ho anche cercato di stampare Tempo in media il valore di p_cpticks e pochi altri e non ha mai avuto valori interessanti. Ecco il mio codice in fase di stampa le informazioni recuperate (l'ho presa da cocoabuilder.com):

- (NSDictionary *) getProcessList { 
    NSMutableDictionary *ProcList = [[NSMutableDictionary alloc] init]; 

    kinfo_proc *mylist; 
    size_t mycount = 0; 
    mylist = (kinfo_proc *)malloc(sizeof(kinfo_proc)); 
    GetBSDProcessList(&mylist, &mycount); 
    printf("There are %d processes.\n", (int)mycount); 

NSLog(@" = = = = = = = = = = = = = = ="); 
    int k; 
    for(k = 0; k < mycount; k++) { 
     kinfo_proc *proc = NULL; 
     proc = &mylist[k]; 
     // NSString *processName = [NSString stringWithFormat: @"%s",proc->kp_proc.p_comm]; 
     //[ ProcList setObject: processName forKey: processName ]; 
     // [ ProcList setObject: proc->kp_proc.p_pid forKey: processName]; 
      // printf("ID: %d - NAME: %s\n", proc->kp_proc.p_pid, proc->kp_proc.p_comm); 
      printf("ID: %d - NAME: %s CPU TIME: %d  \n", proc->kp_proc.p_pid, proc->kp_proc.p_comm, proc->kp_proc.p_pid); 
     // Right click on p_comm and select 'jump to definition' to find other values. 
    } 


    free(mylist); 

    return [ProcList autorelease]; 
} 

Grazie!

EDIT: Ho appena offerto una taglia per questa domanda. Quello che sto cercando in particolare è di ottenere la quantità di tempo che ogni processo spende nella CPU.

Se, oltre a questo, è possibile assegnare a% CPU l'utilizzo di un processo, sarebbe fantastico.

Il codice deve essere ottimale in quanto verrà chiamato ogni secondo e il metodo verrà chiamato su tutti i processi in esecuzione. Preferibile l'obiettivo-C.

Grazie ancora!

EDIT 2

Inoltre, qualsiasi commento sul motivo per cui le persone sono ignorando questa domanda sarebbe anche utile :)

+1

Non credo che le persone ignorano la tua domanda. È solo che la programmazione OS di basso livello per Mac è un argomento molto specializzato. Misurare il tempo reale in cui un processo spende nella CPU è anche un argomento discutibile. – kazanaki

+0

Grazie per il feedback. Per un po 'di tempo mi sono sentito perso nel cyberspazio. Spero che saremo in grado di ottenere presto delle risposte. –

+0

questo non ti aiuterà, ma sembra che nel codice precedente si stampa due volte il pid – rano

risposta

3

Date un'occhiata alla fonte Darwin per libtop.c e in particolare il libtop_pinfo_update_cpu_usage function() . Si noti che:

  1. avrete bisogno di una conoscenza di base dei fondamenti di programmazione Mach di dare un senso di questo codice, in quanto utilizza le porte attività, ecc
  2. Se si desidera usare semplicemente libtop, dovrete per scaricare l'origine e compilarla da soli.
  3. Il processo richiederà i privilegi per accedere alle porte attività per altri processi.

Se tutto ciò suona piuttosto scoraggiante, beh ... ci è un modo che utilizza le API meno esoterici: Basta generare un processo top e analizzare il suo standard output. Uno sguardo rapido sopra la parte superiore (1) pagina man alzato questo piccolo gioiello:

$ top -s 1 -l 3600 -stats pid,cpu,time 

Cioè, campione una volta al secondo per 3600 secondi (un'ora), e l'uscita stdout in forma di registro solo le statistiche per pid, utilizzo della CPU e ora.

Generare e gestire il processo figlio in alto e quindi analizzarne l'output sono tutti semplici esercizi di programmazione Unix.

+0

C'è un modo per ottenere un po 'di codice di esempio per vedere come implementarlo? Non sono nemmeno molto chiaro su quali argomenti passare il metodo :( –

+0

Ho modificato la mia risposta per offrire un'alternativa un po 'meno esoterica :-) C'è un sacco di materiale tutorial sull'uso di NSTask per gestire un processo figlio ... Lo raccomanderei e NSScanner analizzerà l'output di top. –

+0

Grazie mille! Ci stiamo decisamente avvicinando a qualcosa che riesco a fare. Molto bene! :) –

1

Hai dato un'occhiata alla struttura rusage?È stato elencato e commentato come "Informazioni sull'uscita", ma so che contiene le risorse in realtà utilizzate da un processo. Dai uno sguardo allo this page. Ricordo che ho usato getrusage() per calcolare l'esatta quantità di tempo CPU utilizzato nel mio calcolo scientifico per il mio processo corrente, quindi devi solo sapere come interrogare quella struttura per ogni processo nella tua lista credo

+1

getrusage() funziona solo per il processo chiamante e i suoi figli. –

+0

Lo so, l'ho affermato sopra, ma credo che ci sia un modo per interrogare altri processi in modo simile – rano

+0

@rano. Sembra fattibile e ci sto giocando proprio ora. Qualche esempio di codice sarebbe comunque fantastico;) –

Problemi correlati