一,有名管道概述:
有名管道也被称为FIFO文件,是一种特殊的文件。由于linux所有的事物都可以被视为文件,所以对命名管道的使用也就变得与文件操作非常统一,如使用
open,read,write等操作文件的方法对有名管道进行操作。
二、有名管道特点:
- 使不相关的两个进程彼此通信:a. 通过路径名指出,在文件系统中可见;
b. 管道建立后,两进程可按普通文件一样对其操作。 - FIFO遵循先进先出规则:a. 对管道读从开始处返回数据;
b. 对管道写则把数据添加到末尾;
c. 不支持如lseek()等文件定位操作;
三、FIFO文件与普通文件的区别:
FIFO文件在使用上和普通文件有相似之处,但是也有不同之处:
1. 读取Fifo文件的进程只能以”RDONLY”方式打开fifo文件;
2. 写Fifo文件的进程只能以”WRONLY”方式打开fifo文件;
3. Fifo文件里面的内容被读取后,就消失了。但是普通文件里面的内容读取后还存在。
三、操作有名管道的函数:
-
创建有名管道:mkfifo() 【其实就是创建fifo文件,要对这个fifo文件操作就跟普通文件一样】
创建有名管道FIFO:mkfifo() 函数原型: int mkfifo(const char *pathname, mode_t mode); 头文件: 《sys/types.h》《sys/stat.h》 功能: 创建一个fifo文件(有名管道); 参数: pathname:创建fifo文件的名字; mode:访问fifo文件的权限;
返回值: 成功:返回0; 失败:返回-1;
-
删除有名管道:
删除有名管道FIFO:unlink() 函数原型: int unlink(const char *pathname); 头文件: 《unistd.h》 功能: 主要意思是从文件系统中删除一个指定名字的文件,并清空这个文件使用的可用的系统资源,如空间、进程等 参数: pathname:删除mkfifo函数创建fifo文件的名字 返回值: 成功:返回0;失败:返回-1。 创建管道成功后,可使用open()、read()和write()等函数。
为读而打开的管道可在open()中设置O_RDONLY
为写而打开的管道可在open()中设置O_WRONLY与普通文件不同的是阻塞问题
•普通文件的读写时不会出现阻塞问题
•在管道的读写中却有阻塞的可能,
•fifo文件读取后内容就不存在了。
•非阻塞标志:在open()函数中设定为O_NONBLOCK-
阻塞打开与非阻塞打开
- 对于读进程
•若该管道是阻塞打开,且当前FIFO内没有数据,则对读进程而言将一直阻塞到有数据写入
•若该管道是非阻塞打开,则不论FIFO内是否有数据,读进程都会立即执行读操作。即如果FIFO内没有数据,则读函数将立刻返回0 - 对于写进程
•若该管道是阻塞打开,则写操作将一直阻塞到数据可以被写入
•若该管道是非阻塞打开而不能写入全部数据,则读操作进行部分写入或者调用失败
- 对于读进程
四、示例:
写两个程序,一个读fifo文件,一个读fifo文件。
//write
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
void main(void) {
int fd = mkfifo("/home/nan/test/god",0666) ;
fd = open( "/home/nan/test/god",O_WRONLY ) ;
write( fd , "write" , 6 ) ;
close(fd) ;
}
//read
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
void main() {
int fd = open( "/home/nan/test/god",O_RDONLY ) ;
char buf[6] ;
read( fd , buf , 6 ) ;
printf( "read is : %s\n",buf ) ;
close(fd);
unlink( "/home/nan/test/god" ) ;
}
先写进程启动后,处于阻塞状态,除非读进程启动读取后。