进程使用的 CPU 时间

7
我已经成功地实现了这个清单上的代码,获取了运行中所有进程及其ID的列表。现在我需要提取每个进程使用CPU的时间。
我尝试参考代码中的键,但是当我尝试打印“CPU时间刻度”时,我得到所有进程的零值。而且,即使我得到了一个值,我也不确定“CPU时间刻度”是否正是我要查找的内容。
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 */

事实上,我也尝试过打印p_cpticks的时间平均值以及其他一些值,但从未得到有趣的结果。以下是我的代码,它打印了检索到的信息(我从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];
}

谢谢!

编辑:我刚刚为这个问题提供了赏金。我特别想知道每个进程在 CPU 上花费的时间。

如果您能够给出进程正在使用的 %CPU,那就太好了。

代码应该是最优的,因为它将每秒被调用,并且该方法将在所有正在运行的进程上被调用。最好使用 Objective-C。

再次感谢!

编辑2

另外,为什么人们忽略这个问题的任何评论也会很有帮助 :)


1
我不认为人们忽视了你的问题。只是Mac低级操作系统编程是一个非常专业化的话题。测量进程在CPU上真正花费的时间也是一个有争议的话题。 - kazanaki
谢谢您的反馈。有一段时间我感觉自己迷失在了网络空间中。希望我们能尽快得到一些答案。 - Eric Brotto
这并不会对你有所帮助,但似乎在上面的代码中你正在打印两次pid。 - rano
2个回答

4
请查看libtop.c的达尔文源代码,特别是libtop_pinfo_update_cpu_usage()函数。 请注意:
  1. 您需要基本了解Mach编程基础知识才能理解此代码,因为它使用任务端口等。
  2. 如果您想简单地使用libtop,则必须下载源代码并自行编译。
  3. 您的进程将需要权限才能访问其他进程的任务端口。

如果所有这些听起来令人生畏,那么...有一种方法可以使用不太奇怪的API:只需生成一个top进程并解析其标准输出即可。 快速浏览top(1)手册找到了以下信息:

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

即每秒采样一次,持续3600秒(一小时),并以日志形式仅输出pid、CPU使用率和时间的统计信息到stdout。

生成和管理子进程top,然后解析其输出都是直接的Unix编程练习。


有没有办法获取一些示例代码以查看如何实现这个?我甚至不清楚要通过方法传递什么参数 :( - Eric Brotto
我已经编辑了我的答案,提供了一个相对不那么晦涩的替代方案。:-) 有很多关于使用NSTask来管理子进程的教程材料...我建议使用它,并使用NSScanner来解析top的输出。 - Kaelin Colclasure
非常感谢!我们肯定离我能够管理的事物越来越近了。做得好! :) - Eric Brotto
嗨@EricBrotto!! 你能找到进程的CPU使用率吗?请分享一下你完成这个任务的经验。 - Bablu Joshi

0
你有没有看过结构体 rusage?你列出了它并注释为“退出信息”,但我知道它包含了进程实际使用的资源。看一下this page。我记得我在我的科学计算中用了getrusage()来计算当前进程使用的精确CPU时间,所以你只需要知道如何查询每个进程的该结构体即可。

1
getrusage()只适用于调用进程及其子进程。 - Kaelin Colclasure
我知道,我之前已经说过了,但我相信有一种类似的方式可以查询其他进程。 - rano
@rano。这看起来是可行的,我现在正在尝试它。不过,一些示例代码会很棒的 ;) - Eric Brotto
@rano,我觉得你的建议很不错,但它只涉及到当前进程。有没有办法将其应用于所有进程? - Eric Brotto
@Eric Brotto,很抱歉,如之前所述,getrusage()只能用于当前进程或其子进程。我可以提供一些代码来实现此功能,因为我曾经使用过它。我的想法是应该有类似于查询其他进程的东西,但我不确定具体是什么。 - rano
@rano,谢谢你的尝试,但我确实需要适用于所有进程的东西。 :) - Eric Brotto

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接