Fork() 代码未按预期工作 - 层次结构制作
Fork() code not working as expected - Hierarchy making
下午好。
我目前正在开发一个 C 程序,该程序采用一个且只有一个参数,该参数指定要创建的 "child generation" 的数量(自己的父亲已经算作 1 个)。 "wait()" 系统调用不用于此练习(具有 "wait" 调用的版本恰好按预期工作)。
例如,调用 $program 4 应该生成如下层次结构:
进程 A 创建 B
进程 B 创建 C
进程 C 创建 D
打印的消息并不重要,因为它们只是任务的方向。使用以下代码(恰好通过 "wait()" 调用完全按照我想要的方式工作)表明所有子进程都来自同一个父亲,我不明白为什么会这样。
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char *argv[]) {
int counter; pid_t result; int i;
/*
We are going to create as many processes as indicated in argv[1] taking into account that the main father already counts as 1!
*/
if (argc > 2 || argc == 1) {puts("IMPOSSIBLE EXECUTION\n"); exit(-1);}
int lim = atoi(argv[1]);
//We eliminate the impossible cases
if (lim < 1) {puts("IMPOSSIBLE EXECUTION\n"); exit(-1);}
if (lim == 1) {puts("The father himself constitutes a process all by his own, therefore:\n");
printf("Process%d, I'm %d and my father: %d\n", counter, getpid(), getppid());
}
else {
for (i = 0; i < lim; i++) {
result = fork();
if (result < 0) {
printf("Call%d \n", counter); perror("Has failed!");
exit(-1);
}
else if (result) {
break; //Father process
}
else {
counter++; //Child processes increment the counter
printf("Process%d, I am %d and my father: %d\n", counter, getpid(), getppid());
}
}
}
上面代码生成的层次结构不是我预期的...
非常感谢所有帮助。
谢谢
With the following code (which happens to work exactly how I want with
a "wait()" call) states that all the child processes derive from the
same father, which I don't understand why it's happening.
我在测试中没有看到这一点,我也没有任何理由期望您确实是这种情况。但是,如果您看到的是部分或全部 child 进程将进程 1 报告为它们的 parent,那么您可能 看起来 就是这种情况。如果他们原来的 parent 在 child 的 getppid()
调用被处理之前终止,就会发生这种情况。以这种方式孤立的进程继承进程 1 作为它们的 parent。如果 child 的 parent wait()
先终止,那么这种情况就不会发生,但是如果 parent 在分叉 child 之后很快终止,那么结果是完全合理的。
这是您的循环的一个变体,它将在每种情况下报告原始 parent 进程 ID:
pid_t my_pid = getpid();
for (i = 0; i < lim; i++) {
result = fork();
if (result < 0) {
printf("Call%d \n", counter); perror("Has failed!");
exit(-1);
} else if (result) {
break; //Father process
} else {
pid_t ppid = my_pid; // inherited from the parent
my_pid = getpid();
counter++; //Child processes increment the counter
printf("Process%d, I am %d and my father: %d\n", counter, (int) my_pid, (int) ppid);
}
}
你错过了一个关键的函数调用。
for (i = 0; i < lim; i++) {
fflush(stdout); // <============== here
result = fork();
没有它,您的 fork
会将父进程的标准输出缓冲区复制到子进程中。这就是您看到父进程输出重复多次的原因 --- 它的子进程和孙进程继承了输出缓冲区。
Live demo(格式固定,方便阅读)。
下午好。
我目前正在开发一个 C 程序,该程序采用一个且只有一个参数,该参数指定要创建的 "child generation" 的数量(自己的父亲已经算作 1 个)。 "wait()" 系统调用不用于此练习(具有 "wait" 调用的版本恰好按预期工作)。
例如,调用 $program 4 应该生成如下层次结构: 进程 A 创建 B 进程 B 创建 C 进程 C 创建 D
打印的消息并不重要,因为它们只是任务的方向。使用以下代码(恰好通过 "wait()" 调用完全按照我想要的方式工作)表明所有子进程都来自同一个父亲,我不明白为什么会这样。
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char *argv[]) {
int counter; pid_t result; int i;
/*
We are going to create as many processes as indicated in argv[1] taking into account that the main father already counts as 1!
*/
if (argc > 2 || argc == 1) {puts("IMPOSSIBLE EXECUTION\n"); exit(-1);}
int lim = atoi(argv[1]);
//We eliminate the impossible cases
if (lim < 1) {puts("IMPOSSIBLE EXECUTION\n"); exit(-1);}
if (lim == 1) {puts("The father himself constitutes a process all by his own, therefore:\n");
printf("Process%d, I'm %d and my father: %d\n", counter, getpid(), getppid());
}
else {
for (i = 0; i < lim; i++) {
result = fork();
if (result < 0) {
printf("Call%d \n", counter); perror("Has failed!");
exit(-1);
}
else if (result) {
break; //Father process
}
else {
counter++; //Child processes increment the counter
printf("Process%d, I am %d and my father: %d\n", counter, getpid(), getppid());
}
}
}
上面代码生成的层次结构不是我预期的...
非常感谢所有帮助。 谢谢
With the following code (which happens to work exactly how I want with a "wait()" call) states that all the child processes derive from the same father, which I don't understand why it's happening.
我在测试中没有看到这一点,我也没有任何理由期望您确实是这种情况。但是,如果您看到的是部分或全部 child 进程将进程 1 报告为它们的 parent,那么您可能 看起来 就是这种情况。如果他们原来的 parent 在 child 的 getppid()
调用被处理之前终止,就会发生这种情况。以这种方式孤立的进程继承进程 1 作为它们的 parent。如果 child 的 parent wait()
先终止,那么这种情况就不会发生,但是如果 parent 在分叉 child 之后很快终止,那么结果是完全合理的。
这是您的循环的一个变体,它将在每种情况下报告原始 parent 进程 ID:
pid_t my_pid = getpid();
for (i = 0; i < lim; i++) {
result = fork();
if (result < 0) {
printf("Call%d \n", counter); perror("Has failed!");
exit(-1);
} else if (result) {
break; //Father process
} else {
pid_t ppid = my_pid; // inherited from the parent
my_pid = getpid();
counter++; //Child processes increment the counter
printf("Process%d, I am %d and my father: %d\n", counter, (int) my_pid, (int) ppid);
}
}
你错过了一个关键的函数调用。
for (i = 0; i < lim; i++) {
fflush(stdout); // <============== here
result = fork();
没有它,您的 fork
会将父进程的标准输出缓冲区复制到子进程中。这就是您看到父进程输出重复多次的原因 --- 它的子进程和孙进程继承了输出缓冲区。
Live demo(格式固定,方便阅读)。