Unix和Window平台IPC: 匿名管道
时间:2010-09-02 来源:kgisme170
那么我们需要两个管道:Main写入第一个管道的write端,第一个管道的read端和第二个管道的write端绑定到My,而第二个管道的write端给Main来做输出用。
Unix平台用fork()函数,子进程自动继承了父进程声明的各个管道fd,把子进程的stdin/stdout关闭,用dup2把两个管道绑定到子进程的stdin/stdout,然后用execl执行My,这样就可以实现通信了。注意到,因为从文件读入的时候,一次读入就结束了(虽然是两行,但是还是一次read就结束,同理写入管道的时候也是一次结束。所以主程序的while循环里面,应该只包含从管道读出结果的过程
Windows平台没有fork之后的流程,必须直接CreateProcess。而CreateProcess的参数里面指定了子进程的stdin/stdout是否使用特定的管道句柄。因为Windows平台如果混用Posix C函数和Windows API的话,IO的过程会出现一些不可预料的混乱(Microsoft的常用伎俩: 兼容标准,但是又不那么彻底,想要无误运行,还是依赖Windows API)。所以最好完全使用Win32API来编程。
比较而言,Unix调用是简洁的,优雅的,代码很少。函数符合Kiss原则,用不到的功能,不用去管。但是这样的代价就是会有很多"隐含"的知识,这会导致一些隐含的问题。而Win32 API的风格是"显示"的要去指定所有的参数,没有任何隐含的知识。代价就是代码显得繁琐而且罗嗦。但是,所有的知识都体现在一个调用界面里面,阅读和分析代码,反而变得容易了。值得注意的是,Unix平台的read()是遇到内容结束的时候就退出,而在windows上必须保证写端的句柄已经关闭,否则ReadFile会一直处于阻塞状态。
下面是源代码,先贴出Unix平台的。in.txt的内容是:20 30\n5 6\n
> cat calc.C |
再贴出Windows平台的。注意,如果向标准输入写内容不是Write(STD_OUTPUT_HANDLE),会有奇怪的IO问题。(使用printf或者cout的话,会导致读取结果的时候,结果不止一行)为了简化,文件IO被stdin/stdout代替。
#include<windows.h> |