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

peo*_*oro 51 c c++ linux bash fork

如果我运行经典的bash forkbomb:

:(){ :&:&};:
Run Code Online (Sandbox Code Playgroud)

我的系统在几秒钟后挂起.

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

#include <unistd.h>

int main( )
{
    while(1) {
        fork();
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

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


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

:( )
{
    while true
    do
        :
    done
}
Run Code Online (Sandbox Code Playgroud)

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

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

#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;
}
Run Code Online (Sandbox Code Playgroud)

但仍然没有:我可以运行它然后轻易杀死它.它没有我的系统.


为什么?

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

Ara*_*ion 44

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

尝试运行它更长时间.:)

  • 此外,现代Unix倾向于使用copy-on-write来存储虚拟内存.除非每个进程实际写入内存位置,否则它们都将使用相同的物理页面,即使在`exec`之后也是如此.将一些随机的malloc放入并写入malloced内存.我认为这会杀死机器. (26认同)
  • @peoro:技术上你没有.我的观点并不是每个新进程都使用很少的内存,但它实际上不使用额外的内存(除了内核结构).当你执行fork时,子进程使用与父进程完全相同的物理页面,直到它将内容写入内存.即使使用exec,也可以共享可执行映像.将创建一个新的堆栈页面,但是大的性能杀手是交换,除非你做一些写操作,否则这不会发生. (3认同)
  • 不,这不是这种行为的真正原因.这是什么:http://stackoverflow.com/a/19322116/585725 (2认同)