在Linux中从/ proc获取PID列表

问题描述

我正在制作一个程序,可以查看某些过程中是否发生页面错误, 我这样做的方法获取所有进程的PID,并通过查找每个RSS来查看maj_flt/proc/[PID]等,并检查总maj_flt是否有变化

但是为了获取所有正在运行的进程的PID,我需要直接从C程序中获取这些PID,而不使用pstop等现有的shell命令。

有人知道正在运行的PID数据在/proc或其他位置吗?或者,如果还有另一种方法,例如通过我的C程序中的系统调用功能来获得它?

解决方法

不幸的是,没有任何系统调用可以公开PID列表。在Linux中,您应该通过/proc虚拟文件系统来获取此信息。

如果要获得当前正在运行的进程的PID列表,可以使用opendir()readdir()打开/proc并遍历其中的文件/文件夹列表。然后,您可以检查文件名是数字的文件夹。检查后,您只需打开/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);
    }

    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
  ...
,

Linux在/ proc中提供了伪文件系统,以帮助用户获取过程信息,而不是提供系统调用。在/ proc / [pid]中列出目录并解析psinfo或cmdline等文件是获取进程信息的一种实用方法。

我不确定要获取进程的哪些属性,但是我建议您在命令行上键入“ man proc”,以便您可以找出/ proc / [pid]中的哪些文件包含信息。你需要。我猜/ proc / [pid] / stat包含您需要的信息。