!!(100分请教)这是输出转向的BUG吗?

CsLover 2002-10-24 08:49:31
我可能说得比较罗嗦 耐心点看看吧
那天操作系统老师给我们一段代码 要我们画出进程树
代码如下
void Main()
{
int i;
printf("%5d%5d%5d",getpid(),getppid(),getPgid(0));
for(i=0;i<3;i++)
{
if(fork()==0)
{
printf("%5d%5d%5d",getpid(),getppid(),getpgid(0));
}
}
}

作业我是完成了 也了解了老师的意图 可是在做的过程中我发现一个问题,听我细细道来:
为了得到输出结果 我一开始用了">" 输出转向到一个文件 然后去看那个文件
发现子进程每次执行都会把父亲(或者爷爷)进程的相关id都printf一遍 再printf自己 最后结果比预计多出好几行 我也因此被搞得一头雾水 因为子进程不是不会去做fork前面的事吗?
等我直接在shell提示符下运行编译后的文件 看到的结果是理想中的也是理论中的
所以我就觉得用">"来输出转向是不是存在某种问题阿?
我想查帮助 可是man后面不知道打什么 :(
我用的是red hat 7.3 而且已经证实这个问题和shell无关(我在csh下也是如此)
请知道内情的高手点拨一下吧
...全文
26 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
CsLover 2002-10-28
  • 打赏
  • 举报
回复
我给分结贴了 怎么都是0分啊?? 我明明给分了 : (
CsLover 2002-10-28
  • 打赏
  • 举报
回复
这个帖子我给分结贴了 怎么没有效果啊??
CsLover 2002-10-28
  • 打赏
  • 举报
回复
多谢多谢
jfguo 2002-10-28
  • 打赏
  • 举报
回复
W.Richard Stevens 的 apue, 中关于standard i/o library一章
CsLover 2002-10-27
  • 打赏
  • 举报
回复
谢谢各位 我结贴了 jfguo(jfguo)的帮助比较中点 其余几位似乎把自己的主观愿望加在了原码上 改动后使得原码性质改变了 不过还是要感谢各位热心想助
我想查查关于缓冲这方面的知识点 jfguo(jfguo)能给点方向吗?
mrbob0473 2002-10-27
  • 打赏
  • 举报
回复
那么用C++时的“<<”可以得到正确的结果呢?
谢谢!
CsLover 2002-10-27
  • 打赏
  • 举报
回复
我去Linux验证一下 偶去去就来
jfguo 2002-10-26
  • 打赏
  • 举报
回复
for(i=0;i<3;i++)改为for(i=0;i<1;i++)容易看出问题(还有你上面的程序中的两个printf()语句应该有"\n",否则不会是你预想的结果),
如future_path(未来之路) 是standard I/O Library缓存的问题,首先明确几个概念:stdin和stdout是line buffered, 而普通文件是full buffered;使用">"重定向后程序输出已经不是line buffered而变为full buffered.
改过程序后(3改为1,printf()加上\n),
不重定向时输出是: a b c
e d f
重定向后文件内容是: a b c
a b c
e d f
不重定向的结果好理解,而重定向的第二个 a b c其实就是重复了第一个,由于是full buffered, 你在子进程中printf时是将e d f 加到欢存中,程序退出时输出的,结果多输出了一次,这就是原因,3的时候自己分析分析应该会明白的
另外假如printf()中没有\n, 不重定向时也不会是你预想的结果(line buffered 没有\n,不输出),这都是buffer的原因。
blh 2002-10-25
  • 打赏
  • 举报
回复
有什么奇怪的,你的程序意图因该是父进程分别创建3个子进程,分别打印信息,但是你的程序中
if(fork()==0)
{
printf("%5d%5d%5d",getpid(),getppid(),getpgid(0));
}
没有exit(0);,也就是紫禁城打完自己信息后没有退出。它会继续执行循环所以就出现了你看到的现象,呵呵,修改一下你的程序,你可以看得更清楚
#include <stdio.h>

int main()
{
int i;
int j = 0;
printf("main %5d %5d %5d\n",getpid(),getppid(),getpgid(0));

for(i=0;i<3;i++)
{
if(fork()==0)
{
printf("child[%d] %5d %5d %5d\n",j, getpid(),getppid(),getpgid(0));
}
else
j++;
}
sleep(5);
return 0;
}


future_path 2002-10-25
  • 打赏
  • 举报
回复
主要是缓冲的问题,试一试下面这个程序:
void Main()
{
int i;
printf("%5d%5d%5d",getpid(),getppid(),getPgid(0));
for(i=0;i<3;i++)
{
if(fork()==0)
{
fflush(); //这行一定要加,刷新缓存
printf("%5d%5d%5d",getpid(),getppid(),getpgid(0));
}
}
}
CsLover 2002-10-25
  • 打赏
  • 举报
回复
老猫 抱歉啊 程序的意图似乎不仅进入你所说啊
95533 2002-10-24
  • 打赏
  • 举报
回复
你这个程序有点问题,应该比你预计的要多打几行的。
fork=0表示子进程,父进程不会进入的,但子进程会继承父进程的变量i,所以当子进程执行完
if(fork()==0)
{
printf("%5d%5d%5d",getpid(),getppid(),getpgid(0));
}
后不会退出,又会继续进入for循环,同时父进程也在for循环,所以会多打几行,应该改为
if(fork()==0)
{
printf("%5d%5d%5d",getpid(),getppid(),getpgid(0));
return;
}

至于shell执行的为什么不一样我也不清楚,你试试这样运行
yourrunfile 1>/tmp/file.txt 2>&1
看看

23,120

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧