在 Darwin/OSX 中以编程方式确定进程信息
Posted
技术标签:
【中文标题】在 Darwin/OSX 中以编程方式确定进程信息【英文标题】:Determine Process Info Programmatically in Darwin/OSX 【发布时间】:2010-09-18 05:34:15 【问题描述】:我有一个具有以下成员函数的类:
/// 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 并解析输出之外,其余的调用让我望而却步——这是不可接受的。任何帮助将不胜感激。
要求: 在 g++ 4.0 上编译 没有 obj-c OSX 10.5
【问题讨论】:
请描述您为什么要创建一个这样做的类。大多数在 Mac OS X 上运行的软件不需要关心您所描述的任何事情。此外,在为 Mac OS X 开发时,“无 Objective-C”不是一个合理的策略。 【参考方案1】:进程信息来自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 开发人员,但这是免费的):
https://opensource.apple.com/source/top/top-111.20.1/libtop.c.auto.html
稍后编辑:所有这些接口都是特定于版本的,因此在编写生产代码(libproc.h)时需要考虑到这一点:
/*
* This header file contains private interfaces to obtain process information.
* These interfaces are subject to change in future releases.
*/
【讨论】:
【参考方案2】:您可以在 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), 进程组、进程状态等。
【讨论】:
【参考方案3】:大部分信息可以从GetProcessInformation()获得。
顺便问一下,为什么要为返回进程范围信息的函数提供虚拟方法?
这只是CARBON,不适用于可可
【讨论】:
请注意,GetProcessInformation() 是一个 Win32 API 函数,而不是 OP 所说的 Mac OS X。 实际上是@benhoyt,他的链接指向 Apple 文档,其中包含一个名为GetProcessInformation()
的函数,但它是框架的一部分。
GetProcessInformation() 是一个 Mac 调用,但它不测量 CPU 使用率。此外,它已弃用。它是 Mac Toolbox 时代(MacOS X 之前)的旧进程管理器的一部分。我完全不建议在 MacOS X 上使用它。它返回甚至不相关的信息,例如有关进程内存的信息。这是来自 MacOS 9 和更早版本的概念,它没有现代虚拟内存。应用程序只是直接访问计算机的一个内存分区(并且可以修改彼此的内存,无论权限如何)。不要使用它。【参考方案4】:
既然你说没有 Objective-C,我们将排除大多数 MacOS 框架。
您可以使用 getrusage() 获取 CPU 时间,它会为您的进程提供用户和系统 CPU 时间的总量。要获得 CPU 百分比,您需要每秒对 getrusage 值进行一次快照(或者您希望的粒度如何)。
#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 的博文。
【讨论】:
你能解释一下如何在可可中获取正在运行的进程的内存使用情况吗?【参考方案5】:我认为这些值中的大多数都可以在 Mach API 中使用,但是我已经有一段时间没有在那里闲逛了。或者,您可以只查看“ps”或“top”命令的源代码,看看它们是如何做到的。
【讨论】:
以上是关于在 Darwin/OSX 中以编程方式确定进程信息的主要内容,如果未能解决你的问题,请参考以下文章
在 VBA 中以编程方式确定 OnClick 事件的事件处理程序