如果我运行经典的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进程调用了比我的更多的系统调用(例如,访问文件系统)?
答案 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