gpt4 book ai didi

c++ - 当进程退出时得到通知

转载 作者:行者123 更新时间:2023-11-30 04:06:18 25 4
gpt4 key购买 nike

我开发了一个 OSX 守护程序应用程序,用 Qt (C++) 和 Objective-C 编写。我使用内核扩展监视其他应用程序和进程何时启动,但需要知道它们何时终止。

有没有办法接收到其他进程终止的通知,而不必不断轮询目标进程的pid或mach任务?

最佳答案

你可以用 kqueue/kevent 做到这一点。我破解了一个控制台应用程序,然后对其进行了一些重构,以便可以清楚地了解正在发生的事情,并添加了一个辅助函数以更轻松地调用它。仅勉强测试,但希望它能为您提供前进的道路...

哦,是的,请注意这段代码假定主运行循环在应用程序中运行...并且它将从该运行循环中调用 block ...足够简单,可以用另一个运行循环替换它...或者,如果您没有使用任何 CF 运行循环,则必须将 kq 文件描述符添加到您正在使用的任何通知机制中。

编辑

修复了重新启用回调的错误,因为文件描述符回调必须在每次触发后重新启用。此外,使 args 采用多个 PID 来演示监控多个 PID。

当然,您可以轻松地使用调用委托(delegate)方法而不是使用 block ,但这不是重点...

啊....修复资源泄漏......我可能不会修复更多......因为它是一个被黑的例子,但每次我回去阅读它,我都会发现一些错误......也许我会停止阅读:-)

//  main.c

#include <CoreFoundation/CoreFoundation.h>
#include <sys/types.h>
#include <sys/event.h>
#include <sys/time.h>

static void
kqueueCallbackOnExit(CFFileDescriptorRef fileDescriptor,
CFOptionFlags flags,
void *info)
{
int fd = CFFileDescriptorGetNativeDescriptor(fileDescriptor);
struct kevent event;
if (kevent(fd, NULL, 0, &event, 1, NULL) == 1 && event.udata) {
void (^cb)(pid_t) = event.udata;
cb((pid_t)event.ident);
Block_release(cb);
}
CFFileDescriptorEnableCallBacks(
fileDescriptor, kCFFileDescriptorReadCallBack);
}

static int
createOnProcessExitQueue()
{
int kq = kqueue();
if (kq < 0) return -1;

CFFileDescriptorContext context = {
.version = 0,
.info = NULL,
.retain = NULL,
.release = NULL,
.copyDescription = NULL
};
CFFileDescriptorRef kqFileDescriptor = CFFileDescriptorCreate(
NULL, kq, true, kqueueCallbackOnExit, &context);
if (kqFileDescriptor == NULL) {
close(kq);
kq = -1;
return -1;
}

CFRunLoopSourceRef runLoopSource = CFFileDescriptorCreateRunLoopSource(
NULL, kqFileDescriptor, 0);
CFRunLoopAddSource(CFRunLoopGetMain(),
runLoopSource, kCFRunLoopDefaultMode);
CFRelease(runLoopSource);

CFFileDescriptorEnableCallBacks(
kqFileDescriptor, kCFFileDescriptorReadCallBack);
CFRelease(kqFileDescriptor);

return kq;
}

static int
onProcessExit(pid_t pid, void (^callback)(pid_t pid))
{
static int kq;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
kq = createOnProcessExitQueue();
});

void (^cb)(pid_t) = Block_copy(callback);
struct kevent event = {
.ident = pid,
.filter = EVFILT_PROC,
.flags = EV_ADD | EV_ONESHOT,
.fflags = NOTE_EXIT,
.data = 0,
.udata = (void*)cb
};

if (kevent(kq, &event, 1, NULL, 0, NULL) != 1) {
Block_release(cb);
return -1;
}
return 0;
}

int main(int argc, const char * argv[])
{
for (int i = 0; i < argc; ++i) {
pid_t pid = atoi(argv[i]);
printf("watching pid: %d\n", pid);
fflush(stdout);
onProcessExit(pid, ^(pid_t pid) {
printf("process %d just died\n", (int)pid);
fflush(stdout);
});
}

CFRunLoopRun();
return 0;
}

关于c++ - 当进程退出时得到通知,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22960188/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com