#include <unistd.h>
#include <stdio.h>
int main(){
fork();
return 0;
}
在我的理解,叉()将复制父进程,并运行它作为一个子进程;如果是这样的话,上面的程序会破坏吗?因为我对这个程序的理解是:上面的程序将无限期地调用fork(),并最终导致堆栈溢出。只有fork()行的程序不会自行破坏吗?
#include <unistd.h>
#include <stdio.h>
int main(){
fork();
return 0;
}
在我的理解,叉()将复制父进程,并运行它作为一个子进程;如果是这样的话,上面的程序会破坏吗?因为我对这个程序的理解是:上面的程序将无限期地调用fork(),并最终导致堆栈溢出。只有fork()行的程序不会自行破坏吗?
fork
调用不会使子进程或父进程返回到main
的开始并重新开始。它像一个普通的函数一样返回,但它会执行两次,一次在子进程中,一次在父进程中,返回值不同,因此您可以知道哪个是哪个。
因此,在您的程序中,fork
成功,然后这两个过程继续到return 0
并退出。什么坏事都会发生。
的变化将事业问题,虽然:
#include <unistd.h>
int
main(void)
{
for (;;)
fork();
/* not reached */
}
这就是所谓的 “叉炸弹”。因为它调用fork
一个无限循环里面,从来没有检查它是否是父母或孩子,原来的进程变成两个进程,然后4个,然后八点了,......直到你用完的RAM,或至少进程ID 。而且它也不检查故障,因此在呼叫开始失败后它不会停止。所有这些进程将继续永久咀嚼CPU,并且计算机上运行的其他程序都无法取得进展。
早在猛犸象和SunOS 4是比这更糟糕的日子,一个叉炸弹是容易痒痒内核错误和彻底崩溃的小型机,然后BOFH会来找你和他(她)会不高兴。我希望现代性的核心不崩溃,你甚至可以杀死与控制-C的整个过程中指数的树,但我不会去尝试,只是找出。
顺便说一句,return_type whatever()
在C不良作风,因为历史原因,它意味着whatever
需要任何数量的参数。改为总是写return_type whatever(void)
。
良好的生活习惯非常感谢您的回答。你不仅回答了我的问题,还解释了为什么给出的答案是正确的。同时,你也给了我更深的见解。非常感谢。 – asd
除了每个人都指出,相信在技术上孩子应该使用_exit();而不是父调用exit()。 (你用回在您的例子都将调用exit()) – lundman
@lundman这是在这种情况下确定,因为父母没有做任何I/O或调用'fork'之前注册任何'atexit'处理程序,并且由于程序不使用'vfork'。 – zwol
是的,但让让他们从一开始:) – lundman