Linux编程之pipe管道通信(1)

           管道是为了实现进程间相互通信的。可以形象的比喻它为一个管子,管子有两头,不过只能在一端进行读操作,另一端进行写操作

           管道分为两类(1)无名管道,仅适用父子进程间的通信,pipe(fd) fd[0]读 fd[1] 写

                                    (2)有名管道:任意进程可进行通信。

           pipe函数可用于 创建一个管道,以实现进程间通信。我们先介绍基本使用方式,如何使用见下篇。pipe函数原型如下:

           #include <unistd.h>

          int pipe(int fd[2]);pipe函数参数是一个包含两个int型的数组指针,函数成功返回0,并将一对打开的文件描述符填入其参数指向的数组。如果失败,则返回-1,并设置errno。

          通过pipe函数创建的两个文件描述符fd[0] 和fd[1]分别构成管道的两端,往fd[1]写入的数据可从fd[0]读出来。fd[0]只能用于从管道读出数据,fd[1]则只能用于往管道写入数据,而不能反过来使用。如果要实现双向的数据传输,就用该使用两个管道。如图下为管道:可以看出管道属于半双工通信方式。

             默认情况下,这一对文件描述符都是阻塞的。如果用read系统调用来读取一个空的管道,read将被阻塞,直到管道内有数据可读;如果我们用write系统调用往一个满的管道中写入数据,则write将被阻塞,直到管道有足够多的空间可用。但如果程序将fd[0]和fd[1]都设置为非阻塞的,则read和write或由不同的行为,这里涉及到操作系统的互斥访问内容。感兴趣的同学可以参考《操作系统精髓与设计原理》第6章。

        如果管道的斜段文件描述符fd[1]的引用计数减少至0,即没有任何的进程要往管道写入数据,则针对该管道的独断文件描述符fd[0]的read操作将会返回0,意味着读到了文件结束标记(EOF);反之,如果管道的独断文件描述符fd[0]的引用计数减少至0,即没有任何的进程需要从管道中读取数据,则针对该管道的写端文件描述符fd[1]的write操作将失败,并引发SIGPIPE信号。关于SIGPIPE信号,会在后续学习中更博的。

         管道内部传输的数据是字节流,与TCP字节流概念相同,又有细微的区别。应用层程序往一个TCP连接中写入多少字节流的数据,取决于对方的接受通告窗口的大小和本端的拥塞窗口的大小。而管道本身拥有一个容量限制,它规定如果应用程序不将数据从管道读走的话,该管道最多能被写入多少字节的数据。自Linux2.6.11内核起,管道容量的大小默认65536字节。当然我们也可以使用fcntl函数修改管道容量。

         此外,socket的基础API中有一个socketpair函数。它能够方便的创建双向管道。其定义如下:

         #include <sys/types.h>

        #include <sys/socket.h>

        int socketpair(int domain, int type, int protocol, int fd[2]);

        socketpair前三个参数含义与socket系统调用的三个参数完全相同,但domain只能使用UNIX本地协议族AF_UNIX,因为我们仅能在本地使用这个双向管道。最后一参数则和pipe系统调用的参数一样,成功返回0,失败时返回-1并设置errno。

          

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值