我是创造过程的新手......也许是一个基本问题 我创建了固定数量的子进程,每个进程除了打印他们的pid之外什么都不做。问题在于我得到的输出。看看:
int main(){
pid_t pid=0;
int i=0,status=0;
for(i=0;i<3;i++){
pid=fork();
switch(pid){
case 0:{ //Child
printf("\nChild pid: %d",getpid());
exit(0);
break;
}
case -1: {//Error
printf("Error occured in fork");
exit(1);
break;
}
default:{
printf("\nParent id: %d",getpid());
printf("\nIts child id: %d",pid);
wait(NULL);
}
}
输出:
Child pid: 1450
Parent id: 1445
Its child id: 1450
Child pid: 1455Its child id: 1450
Parent id: 1445
Its child id: 1455
Child pid: 1460Its child id: 1455
Parent id: 1445
Its child id: 1460
问题是我不知道为什么只有父进程的第二个print语句出现而不是第一个,如果有的话。我知道我不等待我的子进程结束(坦率地说我不知道我会怎么做),但如果父进程在结束其子进程之前执行,为什么它们的打印语句都不出现,为什么{{1在那一行也被忽略了。
任何帮助将不胜感激
谢谢。
更新:如果我用\n
替换wait(NULL)
它给了我一个完美的输出,没有杂散打印。知道什么可以解决它吗?毕竟他们都做同样的事情。
答案 0 :(得分:1)
问题是有几个进程同时写入同一个文件(您的控制台)而没有任何并发控制或任何锁定。那个,而且ttys是奇怪的生物,充其量也会让奇怪的事情发生。除此之外,请记住printf
是缓冲的。
您的输出应以这种方式阅读:
Child pid: 1450 <- Child #1
Parent id: 1445 <- Parent #1.1
Its child id: 1450 <- Parent #1.2
Child pid: 1455[Its child id: 1450] <- Child #2 with garbage at the end
Parent id: 1445 <- Parent #2.1
Its child id: 1455 <- Parent #2.2
Child pid: 1460[Its child id: 1455] <- Child #3 with garbage at the end
Parent id: 1445 <- Parent #3.2
Its child id: 1460 <- Parent #3.2
你可以尝试将输出重定向到一个文件,看看不是tty会有什么不同。
无论如何,要做正确的扫描,你应该使用任何保证多进程正确性的机制。
<强>更新强>
是的,现在我明白了。您通常会在打印行的开头有“\ n”,而不是最后一行。 Stdout通常是行缓冲的,这意味着缓冲区在看到'\ n'时会刷新到设备。而且由于你在开头有它们,缓冲区中总有一行等待输出。
现在,当你fork
你的进程时,输出缓冲区会被复制,而父进程的最后一行是由孩子打印的(为什么它在之后打印,而不是之前,是对我来说仍然是一个谜。)
无论如何,你添加的新printf
最后有一个'\ n',所以它刷新缓冲区,fork
发现它为空,一切正常。你也可以打电话给fflush(stdout)
,但这很麻烦。
故事的士气是:“当您printf
进行调试时总是在每行的末尾添加\n
,或者您可以获得部分混合内容
答案 1 :(得分:0)
问题在于缓冲和刷新标准输出。
两行都在打印,但没有刷新到你想要的时间输出....取决于输出的位置,(文件,管道,终端,stderr等)printf使用不同的缓冲策略。
我想在你的情况下它只会在换行符上刷新(检查man setbuf
)
将换行符移到末尾而不是开头,例如......
printf("Parent id: %d\n",getpid());
printf("Its child id: %d\n",pid);
并且始终将\ n放在printf的末尾,用于所有printfs。