2013-01-10 49 views
3

我第m个学习的进程间通信......这是代码的bug我fork()和execlp(),execlp之前的printf()没有得到执行

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
int main(void) 
{ 
    int pfds[2]; 
    pipe(pfds); 
    if (!fork()) 
    { 
     printf("I m the child process\n"); 
     close(1); /* close normal stdout */ 
     dup(pfds[1]); /* make stdout same as pfds[1] */ 


     close(pfds[0]); /* we don't need this */ 
     execlp("ls", "ls", NULL); 
} 
else 
{ 
    printf("I m the parent process\n"); 
    close(0);  /* close normal stdin */ 
    dup(pfds[0]); /* make stdin same as pfds[0] */ 
    close(pfds[1]); /* we don't need this */ 
    execlp("wc", "wc", "-l", NULL); 
} 
    return 0; 

}

这些都是一些问题: - 1)我同意在execlp()之后,没有任何东西被执行,但是我的printf()语句在execlp()之前,那么为什么它们不会被执行?

2)该程序在Linux中作为管道命令使用,因此它的执行类似于“ls | wc -l”,但系统知道如何执行程序如“ls | wc -l”而不是“wc -l | ls“.. ?? 3)我认为2)的问题是因为我关闭了标准输出并将其用作我的pfds [1]并关闭了stdin并用作我的垫[0] ..但是如果一个线程退出了之前其他.. ??

4)(使用的Xcode以及GCC IM),运行在GCC上述程序时,它工作得很好,但在Xcode运行时,它显示了一个“SIGTRAP”,并在控制台返回“1”

PLZ帮助...

PS:如果有人告诉我如何在任何一般问题中看到执行单独线程会更好! 谢谢!

+0

对于问题2,你已经知道答案(来自问题3)。一个管道只有在它的两端都有线程运行时才起作用。 –

回答

4
  1. 您的printf正在执行中。但是,它只在重定向stdout后才会刷新,因此其输出未显示在终端上。如果你想在stderr上看到fprintf(stderr, ...),或者在开始搞乱文件描述符之前试试fflush(stdout)

  2. 您将管道的写入结束附加到ls进程的标准输出,并将读取结束标记为wc的标准输入,因此不会出现混淆。

  3. 我不确定你在这里关注什么。 ls进程在完成列表目录后退出,wc退出输入并输出行数。一旦两个持有端点的进程关闭了它(通过退出),管道就会自动清除。

  4. 很难说。调试器显示什么?尽管Xcode调试环境主要针对开发和调试桌面/移动应用程序,但它可能只是某种类型的侥幸。

+0

感谢主席先生,对于我们的帮助!在3)中,我想问一下,“wc -l”是否等到读取结束,即pfds [0]完全充满数据....或者它只是独立运行? – Subbu

+1

它在到达时读取数据。 – duskwuff

+0

即使数据是大尺寸? – Subbu