为什么C-forkbombs不像bash那样工作?

时间:2010-11-22 09:38:14

标签: c++ c linux bash fork

如果我运行经典的bash forkbomb:

:(){ :&:&};:

我的系统在几秒钟后挂起

我试着用C编写一个forkbomb,这里是代码:

#include <unistd.h>

int main( )
{
    while(1) {
        fork();
    }
    return 0;
}

当我运行它时,系统的响应速度会降低,但我可以按^C来杀死该过程(即使在几分钟后)。


上面的代码与我发布的原始bash forkbomb不同:它更像是:

:( )
{
    while true
    do
        :
    done
}

(我没有测试它;不知道它是否挂起系统)。

所以我也尝试实现原始版本;这里是代码:

#include <unistd.h>

inline void colon( const char *path )
{
    pid_t pid = fork( );
    if( pid == 0 ) {
        execl( path, path, 0 );
    }
}

int main( int argc, char **argv )
{
    colon( argv[0] );
    colon( argv[0] );
    return 0;
}

但仍然没有:我可以运行它然后轻易杀死它。它不是挂起我的系统。


为什么?

bash forkbombs有什么特别之处?是因为bash使用了更多的内存/ CPU吗?因为bash进程调用了比我的更多的系统调用(例如,访问文件系统)?

4 个答案:

答案 0 :(得分:44)

那个C程序很小,非常小。另外,fork()这样的程序是非常非常有效的。但是,像Bash这样的解释器在RAM使用方面要贵得多,而且需要一直访问磁盘。

尝试运行它的时间更长。 :)

答案 1 :(得分:4)

真正的原因是,在BASH中,您创建的进程与父进程分离。如果父进程(您最初启动的进程)被终止,则其余进程将继续运行。但是在C实现中,如果父进程被终止,你就会列出子进程死掉,所以它足以让你开始关闭永久分支进程的整个树的初始进程。

我还没有想出一个C forkbomb实现来分离子进程,这样如果父进程死掉它们就不会被杀死。这些实施的链接将不胜感激。

答案 2 :(得分:3)

在你的bash fork炸弹中,你将新的进程放在新的后台进程组中,因此你将无法^C这些进程。

答案 3 :(得分:0)

这主要是因为它的大小。 当你运行bash fork炸弹时,它会将大型怪物程序加载到内存中(相对于你的c程序),每个程序都开始占用你的cpu资源。当大怪物开始繁殖时,无疑会比蜜蜂开始做同样的事情更快。 所以计算机立即挂起。但是如果你让你的c可执行文件运行很长时间,它也会挂起系统。只是时间会更多。 如果你想比较bash的大小和c程序的大小,请检查/ proc // status。 首先使用任何正在运行的bash实例的pid,然后使用任何正在运行的c程序实例的pid