本文共 2749 字,大约阅读时间需要 9 分钟。
一、有名管道的简单说明
无名管道只能在具有亲缘关系的进程间通信,大大地限制了管道的使用。而有名管道的出现则突破了这种限制,它可以使任意两个进程间进行通信。该管道可以通过路径名来指出,并且在文件系统中是可见的。在建立了管道之后,两个进程就可以把它当作普通文件一样进行读写操作,使用非常方便。。不过值得注意的是,FIFO 是严格地遵循先进先出规则的,对管道及FIFO 的读总是从开始处返回数据,对它们的写则把数据添加到末尾,它们不支持如lseek()等文件定位操作。
有名管道的创建可以使用函数mkfifo(),该函数类似文件中的open()操作,可以指定管道的路径和打开的模式。在创建管道成功之后,就可以使用open()、read()和write()这些函数了。与普通文件的开发设置一样,对于为读而打开的管道可在open()中设置O_RDONLY,对于为写而打开的管道可在open()中设置O_WRONLY,在这里与普通文件不同的是阻塞问题。由于普通文件的读写时不会出现阻塞问题,而在管道的读写中却有阻塞的可能,这里的非阻塞标志可以在open()函数中设定为O_NONBLOCK。下面分别对阻塞打开和非阻塞打开的读写进行讨论。
(1)对于读进程
二、有名管道的创建函数
管道创建函数如下所示:
int mkfifo(const char *filename,mode_t mode)filename:要创建的管道
mode : O_RDONLY,读管道
O_WRONLY,写管道
O_RDWR,读写管道O_NONBLOCK:非阻塞
O_CREAT:如果该文件不存在,那么就创建一个新的文件,并用第三个参数为其设置权限
O_EXCL:如果使用O_CREAT 时文件存在,那么可返回错误消息。这一参数可测试文件是否存在
返回值:0成功,其他返回错误代码
操作中经常会出现以下错误如下表所示(方便出错查询):
三、测试
编写一个实例进行测试:需要编写两个独立进程,一个进程用来读取传入的数据,一个进程用来写入数据;在读进程当中首先创建的fifo文件,然后打开并不停的读取FIFO文件当中的内容,在写进程当中打开FIFO文件然后向FIFO文件当中写入相应的内容。具体如下:
读端:
#include写端:#include #include #include #include #include #define FIFO_NAME "yl_fifo" // 定义FIFO文件的名称#define BUFFER_SIZE 256 // 定义缓冲区的大小/* 创建FIFO文件,并以阻塞方式读取FIFO文件当中的内容 * */int main(void){ int ret; int fd; char buf[BUFFER_SIZE]; int buflen; /* 创建FIFO文件 */ if(-1 == access(FIFO_NAME, F_OK)) // 判断FIFO文件是否存在 { ret = mkfifo(FIFO_NAME, 0666); // 以可读可写方式创建一个FIFO文件 if(-1 == ret) { printf("mkfifo error!\n"); return -1; } } fd = open(FIFO_NAME, O_RDONLY); // 打开这个文件 if(-1 == fd) { printf("open error!\n"); return -1; } /* 以阻塞的方式读取文件当中的内容 */ while(1) { memset(buf, 0, BUFFER_SIZE); buflen = read(fd, buf, BUFFER_SIZE); if(buflen > 0) { buf[buflen] = '\0'; if(!strcmp("quit", buf)) // 如果读到的信息是quit,则退出 { return 0; } else // 将读取的信息打印出来 { printf("Read from fifo : %s\n", buf); } } } close(fd); // 关闭这个文件 return 0;}
#include对读端和写端分别进行编译和运行如下所示:#include #include #include #include #include #define FIFO_NAME "yl_fifo" // 定义FIFO文件的名称#define BUFFER_SIZE 256 // 定义缓冲区的大小/* 向FIFO文件当中写入信息 * usage : fifo_write */int main(int argc, char *argv[]){ int fd; char buf[BUFFER_SIZE]; int buflen; if(2 != argc) { printf("usage : %s \n", argv[0]); return -1; } fd = open(FIFO_NAME, O_WRONLY); // 打开这个文件 if(-1 == fd) { printf("open error!\n"); return -1; } /* 将消息写入FIFO文件当中 */ sprintf(buf, "%s", argv[1]); buflen = write(fd, buf, BUFFER_SIZE); if(buflen <= 0) { printf("write error!\n"); return -1; } else { printf("Write to fifo : %s\n", buf); } close(fd); // 关闭这个文件 return 0;}