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(¤t_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_cred
:http://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.
我知道 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(¤t_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_cred
:http://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.