从 Linux 中的 /proc 获取 PID 列表
Getting list of PIDs from /proc in Linux
我正在制作一个程序,可以查看某些进程中是否出现页面错误,
我的方法是获取所有进程的 PID 并查看 rss
、maj_flt
等,方法是在每个 /proc/[PID]
中查找,检查总数是否有变化 maj_flt
.
但是为了获取所有 运行 进程的 PID,我需要直接从我的 C 程序中获取它们,而不使用现有的 shell 命令,例如 ps
、top
等
有人知道 运行 PID 数据存在于 /proc
或其他地方吗?或者如果有另一种方法可以做到这一点,比如在我的 C 程序中通过系统调用函数获取它?
Linux在/proc中提供了伪文件系统来帮助用户获取进程信息而不是提供系统调用。在 /proc/[pid] 中列出目录并解析 psinfo 或 cmdline 等文件是获取进程信息的实用方法。
我不确定你想要获取进程的哪些属性,但我建议你在命令行中输入 'man proc' 以便你可以找出 /proc/[pid] 中的哪些文件] 包含您需要的信息。我想 /proc/[pid]/stat 包含您需要的信息。
不幸的是,没有公开 PID 列表的系统调用。您应该在 Linux 中获取此信息的方式是通过 /proc
虚拟文件系统。
如果您想要当前 运行 个进程的 PID 列表,您可以使用 opendir()
and readdir()
打开 /proc
并在其中迭代 files/folders 的列表。然后您可以检查文件名是数字的文件夹。勾选后,你只要打开/proc/<PID>/stat
就可以得到你想要的信息(特别是你想要第12个字段majflt
)。
这是一个简单的工作示例(可能需要更多的错误检查和调整):
#include <sys/types.h>
#include <dirent.h>
#include <stdio.h>
#include <ctype.h>
// Helper function to check if a struct dirent from /proc is a PID folder.
int is_pid_folder(const struct dirent *entry) {
const char *p;
for (p = entry->d_name; *p; p++) {
if (!isdigit(*p))
return 0;
}
return 1;
}
int main(void) {
DIR *procdir;
FILE *fp;
struct dirent *entry;
char path[256 + 5 + 5]; // d_name + /proc + /stat
int pid;
unsigned long maj_faults;
// Open /proc directory.
procdir = opendir("/proc");
if (!procdir) {
perror("opendir failed");
return 1;
}
// Iterate through all files and folders of /proc.
while ((entry = readdir(procdir))) {
// Skip anything that is not a PID folder.
if (!is_pid_folder(entry))
continue;
// Try to open /proc/<PID>/stat.
snprintf(path, sizeof(path), "/proc/%s/stat", entry->d_name);
fp = fopen(path, "r");
if (!fp) {
perror(path);
continue;
}
// Get PID, process name and number of faults.
fscanf(fp, "%d %s %*c %*d %*d %*d %*d %*d %*u %*lu %*lu %lu",
&pid, &path, &maj_faults
);
// Pretty print.
printf("%5d %-20s: %lu\n", pid, path, maj_faults);
fclose(fp);
}
closedir(procdir);
return 0;
}
示例输出:
1 (systemd) : 37
35 (systemd-journal) : 1
66 (systemd-udevd) : 2
91 (dbus-daemon) : 4
95 (systemd-logind) : 1
113 (dhclient) : 2
143 (unattended-upgr) : 10
148 (containerd) : 11
151 (agetty) : 1
...
您可以使用 openproc
查询虚拟 /proc
文件系统中可用的数据(参见 man 3 openproc
)。 procps
需要库才能编译代码。
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <proc/readproc.h>
// compile with:
// gcc environ.c -lprocps -o bin/environ
int main(){
PROCTAB* proc = openproc(PROC_FILLSTAT);
proc_t proc_info;
memset(&proc_info, 0, sizeof(proc_info));
while (readproc(proc, &proc_info) != NULL) {
printf("%i,%i:\t %lu\n", proc_info.ppid, proc_info.tid, proc_info.maj_flt);
}
closeproc(proc);
}
我正在制作一个程序,可以查看某些进程中是否出现页面错误,
我的方法是获取所有进程的 PID 并查看 rss
、maj_flt
等,方法是在每个 /proc/[PID]
中查找,检查总数是否有变化 maj_flt
.
但是为了获取所有 运行 进程的 PID,我需要直接从我的 C 程序中获取它们,而不使用现有的 shell 命令,例如 ps
、top
等
有人知道 运行 PID 数据存在于 /proc
或其他地方吗?或者如果有另一种方法可以做到这一点,比如在我的 C 程序中通过系统调用函数获取它?
Linux在/proc中提供了伪文件系统来帮助用户获取进程信息而不是提供系统调用。在 /proc/[pid] 中列出目录并解析 psinfo 或 cmdline 等文件是获取进程信息的实用方法。
我不确定你想要获取进程的哪些属性,但我建议你在命令行中输入 'man proc' 以便你可以找出 /proc/[pid] 中的哪些文件] 包含您需要的信息。我想 /proc/[pid]/stat 包含您需要的信息。
不幸的是,没有公开 PID 列表的系统调用。您应该在 Linux 中获取此信息的方式是通过 /proc
虚拟文件系统。
如果您想要当前 运行 个进程的 PID 列表,您可以使用 opendir()
and readdir()
打开 /proc
并在其中迭代 files/folders 的列表。然后您可以检查文件名是数字的文件夹。勾选后,你只要打开/proc/<PID>/stat
就可以得到你想要的信息(特别是你想要第12个字段majflt
)。
这是一个简单的工作示例(可能需要更多的错误检查和调整):
#include <sys/types.h>
#include <dirent.h>
#include <stdio.h>
#include <ctype.h>
// Helper function to check if a struct dirent from /proc is a PID folder.
int is_pid_folder(const struct dirent *entry) {
const char *p;
for (p = entry->d_name; *p; p++) {
if (!isdigit(*p))
return 0;
}
return 1;
}
int main(void) {
DIR *procdir;
FILE *fp;
struct dirent *entry;
char path[256 + 5 + 5]; // d_name + /proc + /stat
int pid;
unsigned long maj_faults;
// Open /proc directory.
procdir = opendir("/proc");
if (!procdir) {
perror("opendir failed");
return 1;
}
// Iterate through all files and folders of /proc.
while ((entry = readdir(procdir))) {
// Skip anything that is not a PID folder.
if (!is_pid_folder(entry))
continue;
// Try to open /proc/<PID>/stat.
snprintf(path, sizeof(path), "/proc/%s/stat", entry->d_name);
fp = fopen(path, "r");
if (!fp) {
perror(path);
continue;
}
// Get PID, process name and number of faults.
fscanf(fp, "%d %s %*c %*d %*d %*d %*d %*d %*u %*lu %*lu %lu",
&pid, &path, &maj_faults
);
// Pretty print.
printf("%5d %-20s: %lu\n", pid, path, maj_faults);
fclose(fp);
}
closedir(procdir);
return 0;
}
示例输出:
1 (systemd) : 37
35 (systemd-journal) : 1
66 (systemd-udevd) : 2
91 (dbus-daemon) : 4
95 (systemd-logind) : 1
113 (dhclient) : 2
143 (unattended-upgr) : 10
148 (containerd) : 11
151 (agetty) : 1
...
您可以使用 openproc
查询虚拟 /proc
文件系统中可用的数据(参见 man 3 openproc
)。 procps
需要库才能编译代码。
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <proc/readproc.h>
// compile with:
// gcc environ.c -lprocps -o bin/environ
int main(){
PROCTAB* proc = openproc(PROC_FILLSTAT);
proc_t proc_info;
memset(&proc_info, 0, sizeof(proc_info));
while (readproc(proc, &proc_info) != NULL) {
printf("%i,%i:\t %lu\n", proc_info.ppid, proc_info.tid, proc_info.maj_flt);
}
closeproc(proc);
}