我希望在 OSX 上的进程退出之前收到通知,以便我可以在进程终止之前收集有关该进程的统计信息。(示例细节:我想要聚合具有许多子进程的进程的 CPU 使用情况,这些子进程很快生成和死亡,但使用大量 CPU。当通过诸如 之类的东西采样 CPU 使用情况时proc_pidinfo,进程的诞生和死亡速率与我的采样相似我的汇总统计数据中没有充分捕获速率。我希望在进程终止时收到通知,以便我可以总结它们的总用户和系统时间。
到目前为止,看起来效果最好的方法是使用libdtrace,但我不知道如何使用该dtrace命令设置进程退出的探测器,更不用说libdtrace从 C 程序设置了。任何有关设置此类 dtrace 探针的提示以及如何使用的教程libdtrace将不胜感激。
编辑:
好吧,根据一些评论者的建议,我成功创建了一个使用 libdtrace 并可靠地触发进程退出的程序。这很棒,但不幸的是我似乎无法获取正在退出的进程的 PID。看来调用printf()我的 D 程序并尝试格式化整数已严重损坏。具体来说,如果我运行这个程序,该程序应该在进程退出时打印出该进程的名称和 PID,但它会严重失败。它打印一些其他整数,事实上,无论我尝试输出什么,都会打印该整数。如果我将 D 程序从
syscall::*exit*:entry {
printf(\"%s %d\\n\", execname, curpsinfo->pr_pid);
};
Run Code Online (Sandbox Code Playgroud)
只为了
syscall::*exit*:entry {
printf(\"%d\\n\", 100);
};
Run Code Online (Sandbox Code Playgroud)
它只是打印出神秘整数的前三位数字。请注意,进程名称是正确的,我相信这只是整数 -> 字符串转换失败。使用上述 D 程序运行主程序dtrace可以正常工作,但我想将其集成到我已经编写了很多内容的 C 程序中,并且将子命令输出通过管道传输到该程序中并不是我想要继续前进的方式。
帮助如何使缓冲输出libdtrace正常工作,或者如何以整数而不是字符串形式获取 PID 会很棒。
有一个关于此主题的 Apple 技术说明。
为了监视任意进程,本指南建议kqueues.
我们可以通过这种方式获取正在运行的进程的PID[无法检测与其他用户一起运行的应用程序(通过切换用户)或这种方式[以编程方式检查进程是否正在Mac上运行。
清单 8 使用 kqueues 监视特定进程
static pid_t gTargetPID = -1;
// We assume that some other code sets up gTargetPID.
- (IBAction)testNoteExit:(id)sender
{
FILE * f;
int kq;
struct kevent changes;
CFFileDescriptorContext context = { 0, self, NULL, NULL, NULL };
CFRunLoopSourceRef rls;
// Create the kqueue and set it up to watch for SIGCHLD. Use the
// new-in-10.5 EV_RECEIPT flag to ensure that we get what we expect.
kq = kqueue();
EV_SET(&changes, gTargetPID, EVFILT_PROC, EV_ADD | EV_RECEIPT, NOTE_EXIT, 0, NULL);
(void) kevent(kq, &changes, 1, &changes, 1, NULL);
// Wrap the kqueue in a CFFileDescriptor (new in Mac OS X 10.5!). Then
// create a run-loop source from the CFFileDescriptor and add that to the
// runloop.
noteExitKQueueRef = CFFileDescriptorCreate(NULL, kq, true, NoteExitKQueueCallback, &context);
rls = CFFileDescriptorCreateRunLoopSource(NULL, noteExitKQueueRef, 0);
CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode);
CFRelease(rls);
CFFileDescriptorEnableCallBacks(noteExitKQueueRef, kCFFileDescriptorReadCallBack);
// Execution continues in NoteExitKQueueCallback, below.
}
static void NoteExitKQueueCallback(
CFFileDescriptorRef f,
CFOptionFlags callBackTypes,
void * info
)
{
struct kevent event;
(void) kevent( CFFileDescriptorGetNativeDescriptor(f), NULL, 0, &event, 1, NULL);
NSLog(@"terminated %d", (int) (pid_t) event.ident);
// You've been notified!
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2599 次 |
| 最近记录: |