不确定的 C 行为?"Fork bomb"



所以我创造了一个"叉子"炸弹。但是,当我在计算机上运行它时,它会杀死计算机上的所有内容,进入黑屏然后自行恢复。

在我朋友的计算机上,当运行相同的完全相同的代码时,他实际上做了一个叉子炸弹,但从未进入杀戮循环。

有什么原因吗?

#include <unistd.h>
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
int main(){
    int pc = 0;
    int* pids = calloc(1025,sizeof(int));
    L1:
        while(1){
            int pid = fork();
            if(pid != 0)
            {
                pc++;
                pids[pc] = pid;
            }
            if(pc == 1024)
            {
                goto L2;
                break;
            }
        }
    L2:
        while(1){
            if(pids[pc] != 0) {
                kill(pids[pc],SIGKILL);
            }
            if(pc == 0)
            {
                goto L1;
                break;
            }
            pc--;
        }
    free(pids);
}

请注意,此代码仅用于娱乐。

更新:

将 PC++. 放在 if 语句之外会导致内核崩溃。有人可以向我解释为什么吗?

从理论上讲,这段代码甚至不起作用。

您可能崩溃的原因是fork()可能会失败,在这种情况下它将返回 -1。当您调用 kill(-1, SIGKILL) 时,它会将SIGKILL发送到系统上的每个进程。如果您以特权用户身份运行,那么这很糟糕的原因应该是显而易见的。

旁注:

  1. fork()的返回类型是 pid_t而不是 int 。在大多数情况下,pid_t恰好适合int,但您应该使用正确的类型。

  2. goto语句之后有一个break声明是没有意义的。永远无法达到break

  3. 如果您在编译器上启用了警告,它可能会告诉您这两个警告。

"

叉炸弹"本质上不能有任何确定性行为。从理论上讲,拥有无限资源的计算机可以毫无问题地继续分叉。但在实践中,我们知道计算机没有无限的资源。因此,不同的操作系统可能以不同的方式处理资源消耗。

通常,当操作系统无法生成进一步的进程时,内核可能会杀死"违规"进程,以释放资源或崩溃或进入不确定状态。进程的指数增长通常很难处理内核,即使它识别它。

因此,您不能期望任何确定性或可重复的行为。

最新更新