在Darwin / OSX中以编程方式确定过程信息
我有一个类与以下成员函数:
/// caller pid virtual pid_t Pid() const = 0; /// physical memory size in KB virtual uint64_t Size() const = 0; /// resident memory for this process virtual uint64_t Rss() const = 0; /// cpu used by this process virtual double PercentCpu() const = 0; /// memory used by this process virtual double PercentMemory() const = 0; /// number of threads in this process virtual int32_t Lwps() const = 0;
这个类的职责是返回有关调用者的过程信息。 物理内存大小很容易通过sysctl调用来确定,而且pid是微不足道的,但是除了在ps或者top上调用popen和parsing输出之外,其余的调用都不见了,这是不可接受的。 任何帮助将不胜感激。
要求:
在g ++ 4.0上编译
没有obj-c
OSX 10.5
处理信息来自pidinfo
:
cristi:~ diciu$ grep proc_pidinfo /usr/include/libproc.h int proc_pidinfo(int pid, int flavor, uint64_t arg, void *buffer, int buffersize);
CPU负载来自host_statistics
:
cristi:~ diciu$ grep -r host_statistics /usr/include/ /usr/include/mach/host_info.h:/* host_statistics() */ /usr/include/mach/mach_host.defs:routine host_statistics( /usr/include/mach/mach_host.h:/* Routine host_statistics */ /usr/include/mach/mach_host.h:kern_return_t host_statistics
有关更多详细信息,请查看top
和lsof
源代码,它们是开源的(您需要注册为Apple开发人员,但免费):
http://www.opensource.apple.com/darwinsource/Current/top-38/libtop.c
稍后编辑:所有这些接口都是特定于版本的,因此在编写生产代码(libproc.h)时需要考虑这一点:
/* * This header file contains private interfaces to obtain process information. * These interfaces are subject to change in future releases. */
既然你说不Objective-C,我们将排除大部分的MacOS框架。
您可以使用getrusage()获取CPU时间,这会为您的进程收取用户和系统CPU时间的总额。 为了获得一个CPU百分比,你需要每秒钟快照一次(或者你想要的粒度)的快照值。
#include <sys/resource.h> struct rusage r_usage; if (getrusage(RUSAGE_SELF, &r_usage)) { /* ... error handling ... */ } printf("Total User CPU = %ld.%ld\n", r_usage.ru_utime.tv_sec, r_usage.ru_utime.tv_usec); printf("Total System CPU = %ld.%ld\n", r_usage.ru_stime.tv_sec, r_usage.ru_stime.tv_usec);
在getrusage结构中有一个RSS字段,但在MacOS X 10.5中似乎总是为零。 Michael Knight几年前写了一篇关于如何确定RSS的博文。
我认为这些价值中的大部分都可以在Mach API中find,但是我已经在那里探索了一段时间了。 或者,你可以看看“ps”或“top”命令的源代码,看看它们是如何做的。
您可以在mac OS中使用以下代码获取进程信息:
void IsInBSDProcessList(char *name) { assert( name != NULL); kinfo_proc *result; size_t count = 0; result = (kinfo_proc *)malloc(sizeof(kinfo_proc)); if(GetBSDProcessList(&result,&count) == 0) { for (int i = 0; i < count; i++) { kinfo_proc *proc = NULL; proc = &result[i]; } } free(result); }
kinfo_proc结构体包含所有关于进程的信息,如进程标识符(PID),进程组,进程状态等。
大部分信息都可以从GetProcessInformation()中获得 。
顺便说一下,为什么虚拟方法的function,返回全过程信息?
这只是碳 ,不可与cocoa一起使用