如何让子进程等待孙子进程?
How to make child process to wait grandchild process?
我试图让一个进程创建 x 个子进程,并且每个子进程创建 y 个子进程。当 x=2, y=2
时看起来像这样
这是我到目前为止所做的,
pid_t managers[x];
pid_t workers[y];
for (int i = 0; i < x; i++) {
if (i == 0) // create first manager process
managers[i] = fork();
else if (managers[i - 1] > 0)
managers[i] = fork();
if (managers[i] == 0)
for (int j = 0; j < y; j++) {
if (j == 0) // create first worker process
workers[j] = fork();
else if (workers[j - 1] > 0)
workers[j] = fork();
}
// manager process waiting for worker process?
for (int j = 0; j < y; j++)
wait(NULL);
}
// director process waiting for manager process?
for (int i = 0; i < x; i++)
wait(NULL);
for (int i = 0; i < x; i++)
printf("managers[%d] = %d\n", i, managers[i]);
当我 运行 这段代码 x=2, y=2 时,最后一个 printf 函数打印了这个,
managers[0] = 0
managers[1] = 0
managers[0] = 0
managers[0] = 0
managers[1] = 0
managers[1] = 0
managers[0] = 0
managers[1] = 0
managers[0] = 0
managers[1] = 0
managers[0] = 0
managers[1] = 0
managers[0] = 0
managers[1] = 0
managers[0] = 0
managers[1] = 0
managers[0] = 0
managers[1] = 0
managers[0] = 22728
managers[1] = 0
managers[0] = 22728
managers[1] = 0
managers[0] = 22728
managers[1] = 0
managers[0] = 22728
managers[1] = 22737
我不明白我的代码的行为,但我猜是我错误地使用了等待函数。我使用 wait()
的方式与将 pthread_join()
用于多个 pthread 的方式相同,但这是错误的方法吗?如何让管理器进程等待它的子工作进程,让主管进程等待管理器进程?
First= 由于缺少声誉,我无法创建评论,因此我写在这里。
第二个=
去看看CodeVault的视频,简直太棒了
这是关于这个主题的第一个=
https://www.youtube.com/watch?v=94URLRsjqMQ&t=561s
这是第二个=
https://www.youtube.com/watch?v=VzCawLzITh0
看完之后,应该不会太难了。
您使用fork()
的方式是错误的。当 fork()
被调用时,内核内部的进程将被拆分,一个新的 child 的 PID 将被创建, parent 将接收 [=43= 的 PID ], child 将收到 0
这里是如何正确使用 fork 的例子:
if ((pid = fork()) == 0) {
//I am a child process
} else {
// I am the parent
}
所以在你的情况下,如果你是child(并开始执行child代码),你需要退出循环,如果你是parent,您需要存储 PID 并继续循环。
默认情况下,只有parent可以等待child和wait()
或waitpid()
。如果 parent 对于 child 没有 wait()
,则 child 将变成 zombie
。现代内核会将这样的 children 分配给 PID 1
(通常是 init(1)
),这将清除僵尸。这被称为 reaping
.
一些内核支持一个系统调用来要求你的 PID 被设置为 sub-reaper 这在这个 post 中有解释,或者在你的情况下,你可以在中间写逻辑 parents等待children.
以下是如何将所有 grandchildren 的 parent 设置为 sub-reaper 的示例:
prctl(PR_SET_CHILD_SUBREAPER, 1, 0, 0, 0);
您需要在开始创建 children 和 grandchildren 之前发出此系统调用,因此在此之后,如果中间 parent 不收集退出状态使用 wait()
,child 将分配给 parent 的 PID
进行收割。
由于自动处理,测试僵尸和收获可能具有挑战性,所以我准备了一个小的 docker 容器来帮助测试收获,可以在 gitgub
我试图让一个进程创建 x 个子进程,并且每个子进程创建 y 个子进程。当 x=2, y=2
时看起来像这样这是我到目前为止所做的,
pid_t managers[x];
pid_t workers[y];
for (int i = 0; i < x; i++) {
if (i == 0) // create first manager process
managers[i] = fork();
else if (managers[i - 1] > 0)
managers[i] = fork();
if (managers[i] == 0)
for (int j = 0; j < y; j++) {
if (j == 0) // create first worker process
workers[j] = fork();
else if (workers[j - 1] > 0)
workers[j] = fork();
}
// manager process waiting for worker process?
for (int j = 0; j < y; j++)
wait(NULL);
}
// director process waiting for manager process?
for (int i = 0; i < x; i++)
wait(NULL);
for (int i = 0; i < x; i++)
printf("managers[%d] = %d\n", i, managers[i]);
当我 运行 这段代码 x=2, y=2 时,最后一个 printf 函数打印了这个,
managers[0] = 0
managers[1] = 0
managers[0] = 0
managers[0] = 0
managers[1] = 0
managers[1] = 0
managers[0] = 0
managers[1] = 0
managers[0] = 0
managers[1] = 0
managers[0] = 0
managers[1] = 0
managers[0] = 0
managers[1] = 0
managers[0] = 0
managers[1] = 0
managers[0] = 0
managers[1] = 0
managers[0] = 22728
managers[1] = 0
managers[0] = 22728
managers[1] = 0
managers[0] = 22728
managers[1] = 0
managers[0] = 22728
managers[1] = 22737
我不明白我的代码的行为,但我猜是我错误地使用了等待函数。我使用 wait()
的方式与将 pthread_join()
用于多个 pthread 的方式相同,但这是错误的方法吗?如何让管理器进程等待它的子工作进程,让主管进程等待管理器进程?
First= 由于缺少声誉,我无法创建评论,因此我写在这里。
第二个= 去看看CodeVault的视频,简直太棒了
这是关于这个主题的第一个= https://www.youtube.com/watch?v=94URLRsjqMQ&t=561s
这是第二个= https://www.youtube.com/watch?v=VzCawLzITh0
看完之后,应该不会太难了。
您使用fork()
的方式是错误的。当 fork()
被调用时,内核内部的进程将被拆分,一个新的 child 的 PID 将被创建, parent 将接收 [=43= 的 PID ], child 将收到 0
这里是如何正确使用 fork 的例子:
if ((pid = fork()) == 0) {
//I am a child process
} else {
// I am the parent
}
所以在你的情况下,如果你是child(并开始执行child代码),你需要退出循环,如果你是parent,您需要存储 PID 并继续循环。
默认情况下,只有parent可以等待child和wait()
或waitpid()
。如果 parent 对于 child 没有 wait()
,则 child 将变成 zombie
。现代内核会将这样的 children 分配给 PID 1
(通常是 init(1)
),这将清除僵尸。这被称为 reaping
.
一些内核支持一个系统调用来要求你的 PID 被设置为 sub-reaper 这在这个 post 中有解释,或者在你的情况下,你可以在中间写逻辑 parents等待children.
以下是如何将所有 grandchildren 的 parent 设置为 sub-reaper 的示例:
prctl(PR_SET_CHILD_SUBREAPER, 1, 0, 0, 0);
您需要在开始创建 children 和 grandchildren 之前发出此系统调用,因此在此之后,如果中间 parent 不收集退出状态使用 wait()
,child 将分配给 parent 的 PID
进行收割。
由于自动处理,测试僵尸和收获可能具有挑战性,所以我准备了一个小的 docker 容器来帮助测试收获,可以在 gitgub