#include <unistd.h>
int main(int argc, char* argv[]) {
while(1)
{
fork();
}
}
我在Linux上运行此程序,终端上没有任何输出,操作系统似乎死了。linux对这种可能耗尽内存的程序有什么保护措施吗?
#include <unistd.h>
int main(int argc, char* argv[]) {
while(1)
{
fork();
}
}
我在Linux上运行此程序,终端上没有任何输出,操作系统似乎死了。linux对这种可能耗尽内存的程序有什么保护措施吗?
Answers:
这就是所谓的叉子炸弹。
linux对这种可能耗尽内存的程序有什么保护措施吗?
并不是的。每个派生都有其自己的虚拟地址空间和内存使用情况的新进程。因此,每个副本相对较小。最终,您将用完系统上的所有物理+交换内存,而内存不足(OOM)杀手将开始杀死单个进程。但是前叉炸弹仍将以同样快的速度(即使不是更快)创建进程。
首先防止这种情况发生的一种方法是,使用来限制用户进程的数量ulimit -u
(假设您使用的是Bash;其他Shell将具有等效功能)。
ulimit
是bash特有的。其他外壳可能具有相同的内置命令,但名称可能不同。
是的,尽管默认情况下可能未启用它。的setrlimit
系统调用定义系统限制-包括每个用户的进程数。
让我们首先在内核API中对其进行研究(因为您提到了“ linux”):您可以将手册页用于setrlimit,这将告诉您执行类似的操作
#include <sys/resource.h>
...
struct rlimit r;
rnew.r_cur = 40;
rnew.r_max = 50;
setrlimit(RLIMIT_NPROC,&r);
这会将每个用户的最大进程数(RLIMIT_NPROC
)设置为40(软限制)和50(硬限制)。
现在,从外壳程序开始,如果您使用bash,则可以使用ulimit
内置命令:
ulimit -u
29089
您可以通过将限制作为参数传递来设置限制:
ulimit -u 100
ulimit --help
将显示您可以设置其他几个限制(一个可能是用户使用的文件描述符的最大数量)。
这取决于您是否要在用户级别或系统级别使用它。在用户级别,ulimit
(或其他外壳程序的相应命令)将是最简单的解决方案。
但是,在系统级别,有一些机制可以防止恶意用户(或只是不使用ulimit)阻止系统。Linux cgroups机制可以按组限制资源。您可以(通过机制pam_systemd
)强制用户会话属于特定组。例如,对于CPU调度程序,这还有其他好处。
/sys/fs/cgroup/
2.在Google中搜索3.通过浏览make menuconfig
4.通过研究/usr/src/linux/Documentation/cgroups
5.通过阅读systemd文档。抱歉,我不能提供更多帮助,但我只使用了那些资源。我在桌面上使用cgroups来控制资源。
由于此处的最新答案已有3年之久了,因此我想指出,较新的内核(自4.3开始)具有明确的支持,可以通过新的“ PIDs子系统”防止叉式炸弹爆炸。(请参阅https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=49b786ea146f69c371df18e81ce0a2d5839f865c和https://git.kernel.org/cgit/linux/kernel/git /torvalds/linux.git/commit/?id=917d8e2d10f40e28aa9e0d824b2e5b8197d79fc2)