gpt4 book ai didi

使用 fork() 创建进程树,然后对它们进行编号并将其显示在数组中

转载 作者:太空宇宙 更新时间:2023-11-04 12:17:11 26 4
gpt4 key购买 nike

我正在尝试理解 fork() 系统调用以在 Linux 上工作,这就是我编写以下 C 程序的原因:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

int main(int argc, char *argv[]) {
int n = atoi(argv[1]);
int i;
pid_t pid;
printf("Main: PID: %d, PPID:%d\n", getpid(), getppid());
for (i = 0; i <= n; i++) {
if (pid = fork()) {
pid = fork();
if (pid > 0) {
return (0);
}
if (i == n) {
printf("We are in the level %d and as a child PID:%d,PPID:%d\n", n,
getpid(), getppid());
}
}
}
return 0;
}

我所做的是:创建深度为 n 的进程树,其中每个进程创建 2 个子进程,然后终止。最后我只是打印出最后一层的 child 的 pids(所以如果 n=3,就会有 8 个 child ,我想看看这些 child 的 pids)。据我了解,代码运行正常。(如果有任何错误,请纠正我)。

在这之后,我想改变我的代码来做这样的事情:

        1
/ \
/ \
/ \
/ \
2 3
/ \ / \
/ \ / \
4 5 6 7

例如,如果 n=2。我想打印出如下内容:

Last Level Children: 1 2 4
Last Level Children: 1 2 5
Last Level Children: 1 3 6
Last Level Children: 1 3 7

为此,我编写了以下代码:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#define SIZE 256

int main(int argc, char *argv[]) {
int n = atoi(argv[1]);
int i, k;
int m = 1;
int j = 0;
int arr[SIZE];
pid_t pid;
arr[j] = m;
m++;
j++;
for (i = 0; i <= n; i++) {
pid = getpid();
if (pid = fork()) {
arr[j] = m;
m++;
j++;
pid = fork();
if (pid > 0) {
arr[j] = m;
m++;
j++;
return (0);
}
if (i == n) {
printf("Process tree: ");
for (k = 0; k <= n; k++) {
printf("%d ", arr[k]);
}
printf("\n");
}
}
}
return 0;
}

但是当我运行程序时,我似乎得到了错误的结果。我在这里做错了什么?感谢您在正确方向上提供的任何帮助。

最佳答案

您的主要问题是您的 child 将继续他们 parent 的循环并创造出您认为更多的 child 。我只能建议您阅读两次 manuel fork()。管理流程创建并不容易。您需要了解您的 child 会复制 (~) 他们 parent 的所有状态。两者都将执行相同的代码,因此您需要注意根据 fork() 的返回值,您的 fork 之后将执行哪些代码。

comment EOF 的建议是不要在一个函数中使用多个 fork()。您会看到我的实现示例通过没有两个 fork() 调用来保持简单,我将调用隔离在一个特定的地方。

这是您第一个代码的正确实现:

#include <stdio.h>
#include <unistd.h>

static int create_two_child(int i, int n);

int main(void) { return create_two_child(0, 2); }

// tail recursive function: child will call this function to create two new
// child
static int create_two_child(int i, int n) {
if (i < n) { // we look our level
// debug output
printf("DEBUG: We are in the level %d and as a child PID:%d, PPID:%d\n", i,
getpid(), getppid());
fflush(stdout); // we don't want child print parent output
for (int j = 0; j < 2; j++) { // we loop to create two child
pid_t pid = fork();
if (pid == -1) { // error
perror("fork()");
return 1;
} else if (pid == 0) { // child
return create_two_child(i + 1, n); // we call ourself with i + 1 and
// stop function here wich return we
// don't want that child continue the
// loop
}
// parent will continue the loop to the number of child wanted
}
} else {
// if we are at max level we show our pid
printf("We are in the level max %d and as a child PID:%d, PPID:%d\n", i,
getpid(), getppid());
}
return 0;
}

你想要显示树的第二个实现:

#include <stdio.h>
#include <unistd.h>

static int create_two_child(size_t *backtrace, size_t id, size_t i, size_t n);

int main(void) {
// we create array to stock id
size_t backtrace[3];
size_t n = sizeof backtrace / sizeof *backtrace;
return create_two_child(backtrace, 1, 0, n);
}

// tail recursive function: child will call this function to create two new
// child
static int create_two_child(size_t *backtrace, size_t id, size_t i, size_t n) {
if (i < n) { // we look our level
for (size_t j = 0; j < 2; j++) { // we loop to create two child
pid_t pid = fork();
if (pid == -1) { // error
perror("fork()");
return 1;
} else if (pid == 0) { // child
backtrace[i] = id + 1;
// id * 2 cause we create 2 child each time
return create_two_child(backtrace, id * 2, i + 1,
n); // we call ourself with i + 1 and
// stop function here wich return we
// don't want that child continue the
// loop
}
id++;
// parent will continue the loop to the number of child wanted
}
} else {
// if we are at max level we show our backtrace
printf("Last Level Children: 1");
for (size_t j = 0; j < n; j++) {
printf(", %zu", backtrace[j]);
}
printf("\n");
}
return 0;
}

关于使用 fork() 创建进程树,然后对它们进行编号并将其显示在数组中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47113181/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com