代码之家  ›  专栏  ›  技术社区  ›  peoro

为什么C叉炸弹不像bash炸弹那样工作?

  •  51
  • peoro  · 技术社区  · 14 年前

    如果我运行经典的bash forkbomb:

    :(){ :&:&};:
    

    我的系统 悬挂 几秒钟后。

    我试着用C语言写一个叉形炸弹,代码如下:

    #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使用了更多的内存/CPU?因为bash进程调用的系统调用(例如,访问文件系统)比我的多得多?

    4 回复  |  直到 14 年前
        1
  •  44
  •   Arafangion    14 年前

    C程序是 微小的 ,真的很小。另外,fork()这样的程序非常非常高效。然而,一个解释器,比如Bash,在RAM使用方面要昂贵得多,并且需要一直访问磁盘。

    试着运行更长时间。:)

        2
  •  4
  •   Shnatsel    11 年前

    这个 真实的 因为在BASH中,您创建的进程与父进程分离。如果父进程(最初启动的进程)被终止,则其余进程将继续运行。但在C实现中,如果父进程被终止,则列出子进程死亡,因此这足以使您开始关闭的初始进程 整体 不断分叉过程的树。

    我还没有想出一个分离子进程的C forkbomb实现,这样如果父进程死亡,它们就不会被杀死。希望能提供此类实现的链接。

        3
  •  3
  •   ninjalj    13 年前

    在bash forkbomb中,您将新进程放入新的后台进程组中,因此您将无法 ^C 他们。

        4
  •  0
  •   bashrc    13 年前

    这基本上是因为它的尺寸。 当你运行bash fork bomb时,它会将大怪物程序加载到内存中(相对于你的c程序),每个程序都开始占用你的cpu资源。当然,当大怪物开始复制时,麻烦比蜜蜂开始复制时来得更快。 所以计算机会立即挂起。但是如果你让你的c可执行文件长时间运行,它也会挂起系统。只是时间会更长。 如果要比较bash的大小和c program check out/proc//status的大小。 首先使用bash的任何运行实例的pid,然后使用c程序的任何运行实例的pid