以编程方式从/ proc读取所有进程状态

时间:2015-05-01 16:45:30

标签: c linux ubuntu

我想使用/ proc文件夹将所有正在运行的进程状态保存在文件中。从这里阅读一些问题和答案我认为我应该使用pstatus结构来确定我想要保存哪些字段(如果我错了,请纠正我?)但我不知道如何有效地循环遍历所有正在运行的流程。

3 个答案:

答案 0 :(得分:10)

在Linux中,进程状态保存在/proc/PID/status伪文件中,并以文本形式表示(其他操作系统的procfs结构完全不同):

$ grep State /proc/self/status
State:  R (running)

所以你需要一个"解析器"对于该文件:

void print_status(long tgid) {
    char path[40], line[100], *p;
    FILE* statusf;

    snprintf(path, 40, "/proc/%ld/status", tgid);

    statusf = fopen(path, "r");
    if(!statusf)
        return;

    while(fgets(line, 100, statusf)) {
        if(strncmp(line, "State:", 6) != 0)
            continue;
        // Ignore "State:" and whitespace
        p = line + 7;
        while(isspace(*p)) ++p;

        printf("%6d %s", tgid, p);
        break;
    }

    fclose(statusf);
}

要阅读您必须使用的所有进程opendir() / readdir() / closedir()并仅打开具有数字字符的目录(其他是sysctl变量等):

DIR* proc = opendir("/proc");
struct dirent* ent;
long tgid;

if(proc == NULL) {
    perror("opendir(/proc)");
    return 1;
}

while(ent = readdir(proc)) {
    if(!isdigit(*ent->d_name))
        continue;

    tgid = strtol(ent->d_name, NULL, 10);

    print_status(tgid);
}

closedir(proc);

或者,您可以使用已经实现它的procps工具。

答案 1 :(得分:2)

下面的代码片段会调用两个C程序:

find /proc -maxdepth 2 -wholename '/proc/[0-9]*/status'  | xargs cat

答案 2 :(得分:0)

这是一个老问题,但绝对是一个相关的问题。

如果您不想自己解析 procfs,则绝对应该查看 pfs。它是一个用于解析大多数用 C++ 编写的 procfs 的库。 (免责声明:我是图书馆的作者)

在 Linux 系统上,每个任务(进程或线程)在 /procfs 目录下都有一个条目。

在枚举 /procfs 下的目录时,您将获得每个正在运行的进程的目录。 在每个目录下,您可以找到两个文件:statstatus,其中包含当前进程状态。

在 man proc(5) 下(几乎正确)描述了可能的状态:

(3) state  %c
    One of the following characters, indicating process state:

    R  Running

    S  Sleeping in an interruptible wait

    D  Waiting in uninterruptible disk sleep

    Z  Zombie

    T  Stopped (on a signal) or (before Linux 2.6.33) trace stopped

    t  Tracing stop (Linux 2.6.33 onward)

    W  Paging (only before Linux 2.6.0)

    X  Dead (from Linux 2.6.0 onward)

    x  Dead (Linux 2.6.33 to 3.13 only)

    K  Wakekill (Linux 2.6.33 to 3.13 only)

    W  Waking (Linux 2.6.33 to 3.13 only)

    P  Parked (Linux 3.9 to 3.13 only)

这几乎是正确的,因为此列表中缺少一个额外的可能值:

    I  Idle

如果您想从 stat 获取值,最简单的方法可能是使用 fopen & fscanf。该格式也在 man proc(5) 下进行了详细描述。 注意:请注意 comm 值格式。他们说它是 %s,但实际上要复杂得多,因为它可能包含空格或任何其他字符,它可能会搞砸您的解析器(使用成熟解析库的另一个原因)。

如果您想从 status 获取值,您可能应该使用 std::ifstream 或类似方法打开文件并使用 std::getline 直到行以 Status: 开头,然后提取您想要的值。