使用下面非常简单的代码,我的系统(Ubuntu Linux 14.04)简直崩溃,甚至不让我的鼠标响应。我不得不强行退出电源按钮。我认为Linux是一个可以容忍处理这些基本程序错误的稳定操作系统。我错过了什么吗?
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <semaphore.h>
void check(int isOkay){
if(!isOkay){
printf("error\n");
abort();
}
}
int main(void){
#define n 1000000
int array[n];
sem_t blocker;
int i;
while(1){
if(!fork()){
for(i = 0; i < n; ++i){
array[i] = rand();
}
check(sem_init(&blocker, 0, 0) == 0);
check(sem_wait(&blocker) == 0);
}
}
return 0;
}
答案 0 :(得分:2)
恭喜,您已发现fork bomb。有贝壳单线可以打造相同类型的havic,而你的打字却少得多。
实际上可以限制用户可以使用ulimit生成的进程数 - 有关详细信息,请参阅链接的维基百科文章的底部。
但是,桌面安装的Ubuntu并不是一个强化的服务器。它首先是为可用性而设计的。如果您需要一个无法崩溃的锁定系统,那么有更好的选择。
答案 1 :(得分:1)
命令ulmit -u
显示可以启动的最大进程数。但是,不要在后台启动那么多进程:您的计算机会花时间在进程之间切换,并且无法完成实际工作。
linux负责处理创建进程的请求,用户可以根据此限制实现其代码。
答案 2 :(得分:1)
这里的主要问题是确定最佳限制。许多软件根本不使用fork()
,所以你把限制设置为像5这样的小吗?某些软件可能会在收到来自网络的请求时创建新进程,因此您是否将限制设置为“最大网络数据包数”?如果你认为大多数软件没有错误,那么你很想设置相对较高的限制,以便正确的软件正常工作。
另一个问题是调度优先级之一。在一个设计良好的系统中,GUI之类的东西将是“高优先级”,如果它想要CPU时间,它会立即抢占正常/低优先级的工作。如果是这种情况,以正常/较低优先级运行的大型叉炸弹将不会影响系统响应用户的能力,并且用户可以毫无问题地杀死叉炸弹。
可悲的是,由于各种原因,Linux中的调度程序不能像那样工作。它确实支持优先级,但要使用它们,您必须是一个“实时”进程,并且必须以root身份运行(这是一个巨大的安全灾难)。如果没有合理的优先级,Linux会假设每个分叉进程都和其他所有进程一样重要,并且CPU / s最终忙着进行分叉,并且没有剩余的CPU时间来响应用户。