使用fork()创建进程的递归树

时间:2018-10-29 08:37:21

标签: c linux unix recursion fork

我正在尝试生成进程树。在图片中可以看到一个示例,该示例是使用参数5运行程序的预期结果。

程序完成后,只有最后一级的进程(叶子)才应打印其pid。

当我使用级别参数1运行程序时,它将输出1个进程。如果级别= 2,则输出= 3个过程。级别= 3,输出= 2个过程。级别= 4,输出= 6个过程。级别= 5,输出= 4个过程。

如您所见,所有奇数级都提供了适当数量的进程,而偶数级则没有。预期结果是2级的1个进程和4级的2个进程。

enter image description here

class Parent < ApplicationRecord
   has_many :children,
     before_remove: -> (_) { puts "before_remove callback" },
     dependent: :destroy
end

class Child < ApplicationRecord
   belongs_to :parent

   before_destroy -> { puts "before_destroy callback" }
end

> child.delete                            # Ran without callbacks
Child Destroy (99.6ms)  DELETE FROM "children" WHERE "children"."id" = $1  [["id", 21]]

> parent.children.delete(other_child)     # Ran with callbacks
before_remove callback
before_destroy callback
Child Destroy (0.4ms)  DELETE FROM "children" WHERE "children"."id" = $1  [["id", 22]]

> parent.children.delete_all              # Ran without callbacks
Child Destroy (1.0ms)  DELETE FROM "children" WHERE "children"."parent_id" = $1  [["parent_id", 1]]

1 个答案:

答案 0 :(得分:2)

使用fork()的明智之处是永远不要忘记,在创建新流程时,您会拥有两个流程:一个常见的错误是处理子案例(if fork() == 0 { child code })而忽略了事实如果子代码未正确分开,则子代码还将在子代码之后执行 代码。可能会不由自主地导致fork bomb

fork_r()的建议代码(实际上是递归的)

void fork_r(int me, int max) {
    if (me == max) {
        printf("Level %d, pid %ld\n", me, (long)getpid());
    }
    else {
        if (fork() == 0) {
            fork_r(me+1, max);
        }
        else if (!(me & 1)) {   // Note the 'else'
            fork_r(me+1, max);
        }
    }
}

上面的代码产生一个fork(),并且在父对象中 测试一个偶数级别,在这种情况下,将执行另一个fork()