【发布时间】:2011-02-22 19:45:13
【问题描述】:
我正在使用 fork() 编写一个简单的 C 程序来创建进程的二叉树。我能够获得我需要的所有输出(进程的 pid、它的父进程和它的两个子进程)。不幸的是,每个分叉的进程都希望打印出列标题。如何确保标头的 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
我尝试了一些想法(包括那些在横幅部分注释掉的想法),但似乎没有任何效果,而且大多数“修复”使问题变得更糟!
【问题讨论】:
-
我想我可以解释一下您看到的奇怪印刷。您的
sleep(2)和printf("\n")可能是fflush(0)s。 -
在
printf之后添加fflush(stdout);可以解决任何问题吗?可能是 stdio 缓冲区被复制到子进程中并且只打印在那里。 -
是的!添加 fflush 确实可以解决多打印问题。我还删除了底部的 \n 打印以避免过多的空白行。此外,如下所述,我必须在进程打印行之后(在 for 循环内)放置一个 fflush。