我正在处理一个项目,其中有许多PID,我需要找出哪些是僵尸进程,然后杀死它们的父进程以杀死最初的僵尸进程。我不确定是否有任何方法可以找出给定PID的PPID是什么。如果有帮助,请告诉我。
在ps命令的源代码中,有一个名为get_proc_stats
的函数,在proc/readproc.h
中定义,它(除其他功能外)返回给定pid
的父进程pid
。你需要安装libproc-dev
来获取该函数。然后可以执行以下操作:
#include <proc/readproc.h>
void printppid(pid_t pid) {
proc_t process_info;
get_proc_stats(pid, &process_info);
printf("Parent of pid=%d is pid=%d\n", pid, process_info.ppid);
}
我已经包含了仅使用系统库的Linux和macOS/BSD版本。
一个纯C仅使用Linux标准库:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXBUF (BUFSIZ * 2)
int pgetppid(int pid) {
int ppid;
char buf[MAXBUF];
char procname[32]; // Holds /proc/4294967296/status\0
FILE *fp;
snprintf(procname, sizeof(procname), "/proc/%u/status", pid);
fp = fopen(procname, "r");
if (fp != NULL) {
size_t ret = fread(buf, sizeof(char), MAXBUF-1, fp);
if (!ret) {
return 0;
} else {
buf[ret++] = '\0'; // Terminate it.
}
}
fclose(fp);
char *ppid_loc = strstr(buf, "\nPPid:");
if (ppid_loc) {
ppid = sscanf(ppid_loc, "\nPPid:%d", &ppid);
if (!ppid || ppid == EOF) {
return 0;
}
return ppid;
} else {
return 0;
}
}
int main () {
int ppid, pid = 373; // my current cron pid
ppid = pgetppid(pid);
printf("PPid = %d\n", ppid);
}
对于macOS和FreeBSD,请使用以下内容:
#include <stdio.h>
#include <sys/sysctl.h>
#include <sys/param.h>
#include <sys/user.h>
int pgetppid(int pid) {
struct kinfo_proc p;
size_t len = sizeof(struct kinfo_proc);
int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, pid };
if (sysctl(mib, 4, &p, &len, NULL, 0) < 0)
return 0;
if (len == 0)
return 0;
int ret;
#if defined(__APPLE__)
ret = p.kp_eproc.e_ppid; // macOS
#elif defined(__FreeBSD__)
ret = p.ki_ppid; // FreeBSD
#else
#error "Not supported, try adding an elif for this OS"
#endif
return ret;
}
int main () {
int ppid, pid = 2420; // my current cron pid
ppid = pgetppid(pid);
printf("PPid = %d\n", ppid);
}
我在 macOS 上找到了一种替代方案,受到另一个答案的启发。您可以使用未记录的“libproc”方法。
要在 Swift 中使用 libproc,请将以下行添加到您的桥接标头中:
#import <libproc.h>
然后您可以使用此示例代码获取ppid:
let pid = pid_t(12345)
var shortinfo = proc_bsdshortinfo()
let status = proc_pidinfo(pid, PROC_PIDT_SHORTBSDINFO, 0, &shortinfo, Int32(MemoryLayout.size(ofValue: shortinfo)))
guard status > 0 else {
let errno_stored = errno
let errorDescription = String(cString:strerror(errno_stored)!)
throw NSError(domain: "com.apple.libproc", code: Int(errno_stored), userInfo: [NSLocalizedDescriptionKey: errorDescription])
}
let ppid = pid_t(shortinfo.pbsi_ppid)
函数 getppid() 这样做:
#include <unistd.h>
int main()
{
pid_t ppid;
ppid = getppid();
return (0);
}
libproc
中有一个名为get_proc_stats
的函数可以实现你想要的功能。但似乎已经从公共接口中删除了。替代方法是使用openproc
和readproc
来获取pid。我会回答,但我自己无法使其工作(在readproc
中崩溃)。我不知道您使用的操作系统,因此可能不适用。更多阅读这里,这里和这里。 - Paul Rooney/proc
文件系统;在BSD上,则需要调用sysctl()
函数。至于其他系统,我不是很清楚... - Toby Speight