linux利用管道实现进程通信,Linux通过匿名管道进行进程间通信( 三 )


四、把管道用作标准输入和标准输出
下面来介绍一种用管道来连接两个进程的更简洁方法 , 我们可以把文件描述符设置为一个已知值 , 一般是标准输入0或标准输出1 。这样做最大的好处是可以调用标准程序 , 即那些不需要以文件描述符为参数的程序 。
为了完成这个工作 , 我们还需要两个函数的辅助 , 它们分别是dup函数或dup2函数 , 它们的原型如下
#
int dup(int );
int dup2(int , int );
dup调用创建一个新的文件描述符与作为它的参数的那个已有文件描述符指向同一个文件或管道 。对于dup函数而言 , 新的文件描述总是取最小的可用值 。而dup2所创建的新文件描述符或者与int 相同 , 或者是第一个大于该参数的可用值 。所以当我们首先关闭文件描述符0后调用dup , 那么新的文件描述符将是数字0.
例子
在下面的例子中 , 首先打开管道 , 然后fork一个子进程 , 然后在子进程中 , 使标准输入指向读管道 , 然后关闭子进程中的读管道和写管道 , 只留下标准输入 , 最后调用函数来启动一个新的进程od , 但是od并不知道它的数据来源是管道还是终端 。父进程则相对简单 , 它首先关闭读管道 , 然后在写管道中写入数据 , 再关闭写管道就完成了它的任务 。源文件为pipe2.c , 代码如下:
#
#
#
#
int main()
int= 0;
int pipes[2];
const char data[] = "123";
pid_t pid;
if(pipe(pipes) == 0)
pid = fork();
if(pid == -1)
(, "Fork !\n");
exit();
if(pid == 0)
//子进程中
//使标准输入指向[0]
close(0);
dup(pipes[0]);
//关闭pipes[0]和pipes[1] , 只剩下标准输入
close(pipes[0]);
close(pipes[1]);
//启动新进程od
("od", "od", "-c", 0);
exit();
else
//关闭pipes[0],因为父进程不用读取数据
close(pipes[0]);
= write(pipes[1], data, (data));
//写完数据后 , 关闭pipes[1]
close(pipes[1]);
("%d - Wrote %d bytes\n", (), );
exit();
运行结果为:
从运行结果中可以看出od进程正确地完成了它的任务 , 与在shell中直接输入od -c和123的效果一样 。
五、关于管道关闭后的读操作的讨论
现在有这样一个问题 , 假如父进程向管道[1]写数据 , 而子进程在管道[0]中读取数据 , 当父进程没有向[1]写数据时 , 子进程则没有数据可读 , 则子进程会发生什么呢?再者父进程把[1]关闭了 , 子进程又会有什么反应呢?
当写数据的管道没有关闭 , 而又没有数据可读时 , read调用通常会阻塞 , 但是当写数据的管道关闭时 , read调用将会返回0而不是阻塞 。注意 , 这与读取一个无效的文件描述符不同 , read一个无效的文件描述符返回-1 。
六、匿名管道的缺陷
看了这么多相信大家也知道它的一个缺点 , 就是通信的进程 , 它们的关系一定是父子进程的关系 , 这就使得它的使用受到了一点的限制 , 但是我们可以使用命名管道来解决这个问题 。命名管道将在下一篇文章:Linux进程间通信——使用命名管道中介绍 。
总结
【linux利用管道实现进程通信,Linux通过匿名管道进行进程间通信】以上就是本文关于Linux通过匿名管道进行进程间通信的全部内容 , 希望对大家有所帮助 。感兴趣的朋友可以继续参阅本站其他相关专题 , 如有不足之处 , 欢迎留言指出 。感谢朋友们对本站的支持!