管道的概念
数据在管道中是以字符流的形式传送的,即以字节为单位的顺序数据。
Linux把管道看作是一种文件,采用文件管理的方式对管道进行管理,但是管道不使用外存,而是使用物理内存存放传送的数据。
无名管道只能在父子进程之间进行通信
有名管道可以在任意进程间使用
Linux管道可以在终端命令行中使用,也可以在程序中使用。
无名管道
创建:
#include
Int pipe(int filedes[2]);
参数:
Filedes[0]:读取管道文件的标识号
Filedes[1]: 写入管道的文件标识号
在管道建立后,在程序中就可以使用读写文件函数,如read,write函数,从管道中读取和写入数据。
在父子进程进行通信的时候,要先用父进程pipe()创建管道,然后用fork()创建子进程,不然子进程不能继承到父进程的管道资源,导致父子进程间不能通信。
通信时,可以由父进程用write(filedes[1])写入数据,子进程用read(filedes[0])读出数据,管道通信方向一旦建立以后将不能在更改,所以无名管道通信时单工的通信方式。
父进程的filedes[0]不用,可以使用close(filedes[0])关闭,子进程的filedes[1]也一样。
Linux中,管道缓冲区大小有全局符号常量PIPE_BUF确定,缺省值是一个物理页面,4k,在/include/linux/limits.h中定义如下:
#define
命名管道
命名管道完全纳入文件系统进行管理,他是linux的一种特殊文件,具有完整的文件属性,所以称为FIFO文件。
命名管道和无名管道一样使用内存缓存区进行数据的传送。
命名管道的建立:
#incluide
Int mkfifo(const char *path,mode_t mode);
Path: 指明创建命名管道的路径和文件名
Mode:指明管道的访问权限
返回值:成功0,失败负值
Mknod(path,model S_FIFO,0);
创建命名管道成功以后,其他进程就可以像操作普通文件一样对管道进程操作,如read、write、close,但是lseek不能对管道文件进行操作。
Int msgget(key_t key,int magflg);
Int msgctl(int msqid,int cmd,struct msqid_ds *buf);
Int msgsend(int msgid,struct msgbuf *msgp,int msgsz,int msgopt);
Int msgrcv(int msgid ,struct msgbuf *msgp,int msgsz,int msgtyp,int msgopt);