C 中是否有一种编程方式来确定 Linux 下的一组进程中曾使用过的进程数?

Is there a programmatic way in C to determine the number of processes ever used in a group of processes under Linux?

我知道 sysinfo() 函数 returns 一个 procs 参数代表当前 运行 在您的 Linux 系统上的进程总数。

但是,setrlimit()getrlimit() 函数的 RLIMIT_NPROC 参数限制了一个进程可以拥有的子进程的数量。

为了让系统强制执行该数字,我想它知道该 中的当前进程数。这个号码方便吗?

我认为你最后的说法不一定正确。一个组中的进程数可能多于 RLIMIT_NPROC,例如,如果子进程创建自己的子进程。尽管 none 违反了限制,但它们都在同一组中。

但无论如何,您一定可以通过阅读和解析 procfs 来获取信息。给定一个进程的组,您可以搜索其他 /proc/<pid>/stat 伪文件以查找具有相同组的文件(页面中的 pgrp 行。)但是,这可能效率低下,或者实施起来很烦人。

为了强制执行 RLIMIT_NPROC 限制,linux 内核读取 copy_process 函数中的 &p->real_cred->user->processes 字段(例如在 fork() 上) http://lxr.free-electrons.com/source/kernel/fork.c?v=4.8#L1371

 1371         if (atomic_read(&p->real_cred->user->processes) >=
 1372                         task_rlimit(p, RLIMIT_NPROC)) {

sys_execve(fs/exec.c 中的do_execveat_common):

1504    if ((current->flags & PF_NPROC_EXCEEDED) &&
1505        atomic_read(&current_user()->processes) > rlimit(RLIMIT_NPROC)) {
1506        retval = -EAGAIN;
1507        goto out_ret;

因此,如果 processes 大于 RLIMIT_NPROC,函数将失败。此字段定义为 struct user_struct 的一部分(使用 struct cred real_cred in sched.h 作为

访问
 atomic_t processes;    /* How many processes does this user have? */

所以进程计数是按用户计算的。

如果失败,copy_process中的字段会减少:

1655 bad_fork_cleanup_count:
1656    atomic_dec(&p->cred->user->processes);

字段的增量在copy_credhttp://code.metager.de/source/xref/linux/stable/kernel/cred.c#313

313 /*
314 * Copy credentials for the new process created by fork()
315 *
316 * We share if we can, but under some circumstances we have to generate a new
317 * set.
318 *
319 * The new process gets the current process's subjective credentials as its
320 * objective and subjective credentials
321 */
322 int copy_creds(struct task_struct *p, unsigned long clone_flags)

339         atomic_inc(&p->cred->user->processes);

372 atomic_inc(&new->user->processes);

手册页说这是每个用户的限制:http://man7.org/linux/man-pages/man2/setrlimit.2.html

   RLIMIT_NPROC
          The maximum number of processes (or, more precisely on Linux,
          threads) that can be created for the real user ID of the
          calling process.  Upon encountering this limit, fork(2) fails
          with the error EAGAIN.