如果我启动一个非常繁重(内存/CPU密集型)运行非常长时间的进程,操作系统会在一段时间后任意终止它吗?
即是否存在任何限制,超过该限制操作系统将停止后台进程的运行?
这些限制可以配置吗?它们在哪里定义的?
答案1
是的,确实有这样的限制。他们叫资源限制(r限制)。有十几个不同的限制。 CPU 时间、内存、打开文件数等。
当进程超出不同的限制时,内核向进程发送不同的信号。如果进程没有正确反应,它将被杀死。
对于每个 rlimit 有两个值。第一个是电流限制。第二个是最大限制(这是您可以设置的最大限制)。只有root(更准确地说是CAP_SYS_RESOURCE
有能力的用户)才允许增加最大限制或将当前限制设置为大于最大限制。
有getrlimit()
系统setrlimit()
调用来操纵限制。
默认情况下,大多数资源限制包含巨大的值,这意味着没有限制。当然,由于内核设计限制、可用 RAM、磁盘上的可用空间等,存在实际限制。
答案2
有多种方法可以实现这样的策略,但有一个相当明显的原因为什么它默认不存在:因为系统旨在发挥其最大潜力。打个比方:如果你买了一辆时速 200 公里的汽车,它有一个 100 升的油箱,你可能不希望它由软件控制,将速度限制在 100 公里/小时,并在油箱空了 2/3 时停车,即使您已经开车“很长时间”。
请注意,“长时间运行”没有通用的定义。 40分钟是长跑吗? 8小时怎么样? 24小时? 3天?一周、一个月还是一年?这些都不是那么不寻常。
关于rasen提到的资源限制,这是您“实施此类政策”的主要手段。您实际上并没有问如何做到这一点,所以我不会浪费时间深入探讨,但是,您确实询问了限制。至于CPU和内存,则没有。这是来自getrlimit
/setrlimit
系统调用手册页:
getrlimit() 和 setrlimit() 系统调用分别获取和设置资源限制。每个资源都有一个关联的软限制和硬限制,由 rlimit 结构定义 [...]值 RLIM_INFINITY 表示对资源没有限制(在 getrlimit() 返回的结构中和传递给 setrlimit() 的结构中)。
因此,以编程方式检查这一点相对容易:
#include <stdio.h>
#include <sys/resource.h>
#include <errno.h>
#include <string.h>
#include <stdint.h>
int main (void) {
struct rlimit rl;
int resources[] = {
RLIMIT_CPU,
RLIMIT_DATA,
RLIMIT_AS,
RLIMIT_RSS
};
char labels[][16] = { "CPU", "Data", "Virtual", "Resident" };
int rlen = sizeof(resources) / sizeof(int);
printf("RLIM_INFINITY is %lu\n", (uint64_t)RLIM_INFINITY);
for (int i = 0; i < rlen; i++) {
if (getrlimit(resources[i], &rl) != 0) {
fprintf(stderr,"!!%s\n", strerror(errno));
return -1;
}
printf("%8s soft: %lu hard: %lu\n",
labels[i],
(uint64_t)rl.rlim_cur,
(uint64_t)rl.rlim_max
);
}
return 0;
}
你可以自己编译gcc -std=gnu99
并尝试一下。这是最明确的信息来源,因为它直接查询内核。除非有人故意在您的系统上配置限制,否则您会得到类似的结果:
RLIM_INFINITY is 18446744073709551615
CPU soft: 18446744073709551615 hard: 18446744073709551615
Data soft: 18446744073709551615 hard: 18446744073709551615
Virtual soft: 18446744073709551615 hard: 18446744073709551615
Resident soft: 18446744073709551615 hard: 18446744073709551615
为了向非程序员澄清:“RLIM_INFINITY”值是一个旨在指示“无穷大”或无限制的值(因为计算机无法将无穷大表示为数字)。 RLIMIT 字段在手册页中进行了解释,总结一下:
RLIMIT_CPU:CPU 时间限制(以秒为单位)。
RLIMIT_DATA:进程数据段(已初始化数据、未初始化数据和堆)的最大大小。
RLIMIT_AS:进程虚拟内存(地址空间)的最大大小(以字节为单位)。
RLIMIT_RSS:指定进程驻留集(RAM 中驻留的虚拟页数)的限制(以页为单位)。
它们对应于您可以在top
(CPU、DATA、VIRT 和 RSS)中看到的实际使用值。
再说一遍:在普通的 Linux 系统上,每个进程的 CPU 或内存没有限制,但你可以这样设置。