gpt4 book ai didi

c - fork() 导致为每个进程打印列标题

转载 作者:太空宇宙 更新时间:2023-11-04 00:55:16 25 4
gpt4 key购买 nike

我正在编写一个简单的 C 程序,使用 fork() 创建进程的二叉树。我能够获得我需要的所有输出(进程的 pid、它的父进程和它的两个子进程)。不幸的是,每个 fork 进程都想打印出列标题。如何确保 header 的 printf 仅执行一次?

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

int main(int argc, char *argv[]){

//Declarations
int i;
int child_1_pid, child_2_pid;
int num_levels = atoi(argv[1]);

//Output banners
//execlp("/bin/echo", "echo", "Level\tProcs\tParent\tChild1\tChild2\nNo.\tID\tID\tID\tID", (char *) NULL);
//if(getpid() > 0)
printf("Level\tProcs\tParent\tChild1\tChild2\nNo.\tID\tID\tID\tID");

//Creates binary tree of processes
for(i = 0; i < num_levels; i++){
if((child_1_pid = fork()) && (child_2_pid = fork())){
printf("\n%d\t%d\t%d\t%d\t%d", i, getpid(), getppid(), child_1_pid, child_2_pid);
sleep(2); //prevents parent from terminating before child can get ppid (parent's pid)
break; //why?
}
}//end for

printf("\n"); //EXPLAIN ME!!
exit(0);
}//end main

还有一些代码(确实是错误检查),但我真正的问题是输出横幅部分下的 printf 执行了多次,给出了这样的输出(但正确对齐):

Level Procs   Parent  Child1  Child2
No. ID ID ID ID
No. ID ID ID ID
No. ID ID ID ID
No. ID ID ID ID
No. ID ID ID ID
No. ID ID ID ID
No. ID ID ID ID
0 30796 24743 30797 30798
1 30797 30796 30799 30800
1 30798 30796 30801 30802

我已经尝试了一些想法(包括那些在横幅部分被注释掉的想法),但似乎没有任何效果,而且大多数“修复”使问题变得更糟!

最佳答案

首先,for 循环中的 if 没有按您希望的方式运行。请记住,在 fork 之后,它在父进程中返回子 PID,在子进程中返回 0。因此在循环内部,第一个 fork 为父级中的 child_1_pid 赋值并继续到第二个子句。 child 不输入 if 而是继续下一个 for 循环迭代。第二个子句也是如此。所以只有主进程应该能够进入 if 的主体,但没有子进程。我想知道为什么输出表明不是这样。

所以要得到你的“二叉树”,你实际上应该有这个:

// COMPLETELY UNTESTED
for(i = 0; i < num_levels; i++){
if (!(child_1_pid = fork()) || !(child_2_pid = fork())) {
printf("\n%d\t%d\t%d\t%d\t%d", i, getpid(), getppid(), child_1_pid, child_2_pid);
// A child process, go on to next iteration.
continue;
}

// A parent process. Wait for children, then stop.
if (child_1_pid) wait();
if (child_2_pid) wait();
break;
}

横幅的奇怪输出与流的刷新有关。通常,fprintf 仅在换行符 (\n) 上刷新,IIRC。所以 fork 之后的缓冲区中仍有内容尚未被刷新,每个 child 运行 printf("\n"); 从而刷新缓冲区内容。

解决方案是在第一个 printf 的末尾添加一个“\n”,或者在 for 循环之前调用 fflush(stdout);

关于c - fork() 导致为每个进程打印列标题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5083083/

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