《基于Linux的C编程与内核导读》连载(12)
时间:2007-05-07 来源:gaowp
3.3.4 进程间管道通信(二)
在上一节中我们编写了进程间管道通信的一个程序,本节我们学习在管道读、写操作与主程序不在同一个文件中时如何处理。上一节由于是在同一个文件中,我们的读写操作可以直接对管道进行操作,本节将利用输入输出重定向对管道进行操作。这中间关键是系统调用dup()和execl()的使用。
系统调用dup()函数的功能是输入输出重定向,其原型是:
#include <unistd.h> int dup(int fd); |
dup系统调用只有一个参数fd,它是一个指向文件的标志符。通过此系统调用我们可以把管道的读写操作进行重定向,具体用法见下面的例子。
系统调用execl()函数是exec系统函数重的一个,它的作用是用指定的程序文件和数据立即代替原进程的程序区和数据区,然后开始执行新的程序。在linux系统中,exec系统调用实际上是使程序执行的唯一方法。
主文件pipeline.c
/**********本程序是主文件,用于调用管道读写子程序*********/ #define STD_INPUT 0 /*定义标准输入为0*/ #define STD_OUTPUT 1 /*定义标准输出为1*/ int fd[2]; void pipeline(char *process1,char *process2);
int main() { static char process1[]=”father1”,process2[]=”child1”; pipe(fd); /*创建管道*/ pipeline(process1,process2); /*调用子函数pipeline*/ return 0; }
pipeline(char *process1,char *process2) { int i; while((i=fork())==-1); /*创建子进程 */
/*以下是父进程代码,将标准输出重定向为管道的输入端fd[1],并执行father1进程*/ if(i>0) { close(fd[0]); close(STD_OUTPUT); dup(fd[1]); close(fd[1]); execl(process1, process1,0); /*执行father1程序*/ /*若执行了下一句,则说明execl执行发生错误*/ printf(“-----father failed.\n”); } /*父进程代码结束*/
/*以下是子进程代码,将标准输入重定向为管道的输出端fd[0],并执行child1进程*/ else { close(fd[1]); close(STD_INPUT); dup(fd[0]); close(fd[0]); execl(process2, process2,0); /*执行child1程序*/ /*若执行了下一句,则说明execl执行发生错误*/ printf(“-----child failed.\n”); } } |
编制“管道写”程序father1.c作为父进程的一部分工作,其内容如下:
/**********本程序用于管道写操作 **************/ #define STD_OUTPUT 1 /*定义标准输出为1*/ main() { static char string[]={”parent is using pipe write.”}; int len; len=sizeof(string); /*此时STD_OUTPUT端为管道输入端fd[1]*/ write(STD_OUTPUT,string,len); /*通过write向管道写入字符串*/ exit(0); } |
编制“管道读”程序child1.c作为子进程的一部分工作。其内容如下:
/**********本程序用于管道读操作 **************/ #define STD_INPUT 0 /*定义标准输入为0*/ main() { char output[30]; /*此时STD_INPUT端为管道输出端fd[0]*/ read(STD_INPUT,output,30); /*通过read从管道读出字符串*/ printf(“%s\n”,output); return(0); } |
编译:
gcc –o child1 child1.c gcc –o father1 father1.c gcc –o pipeline pipeline.c |
运行:
#./pipeline |
结果分析:
函数pipeline.c的作用创建一个子进程。父进程将标准输出重定向为管道的输入端fd[1],并执行father1进程;子进程将标准输入重定向为管道的输出端fd[0],并执行child1进程。进程father1的作用是通过系统标准写操作向管道写入字符串“parent is using pipe write”;进程child1的作用是通过系统标准读操作从管道读出该字符串。所以此程序运行得到的结果为:
parent is using pipe write. |