通过命令mkfifo +管道名 (创建有名管道文件)
有名管道的使用
1.同时具备读与写的两端都需要打开管道文件才使用有名管道,如只有一方,则打开时阻塞
2.所有有名管道内保存的数据都与管道文件无关,管道文件只提供操作管道的方式
有名管道的几种情况:
读管道:
1.默认情况下操作都是阻塞的(以下几条的前提)
2.写端打开管道,管道无数据,读端读阻塞
3.造成阻塞的两种原因:
1.管道内有数据,但是其他进程正在读取
2.管道内无数据,读进程阻塞
4.一个进程多个读端,只有第一个进程读端阻塞,其他读端不阻塞(多线程)
写管道:
1.默认情况下操作都是阻塞的(以下几条的前提)
2.写端向管道内写入数据,内核帮助写端保证数据的原子性判断
1.写的数据大于4096,不保证数据的原子性
2。写的数据小于4096,保证数据原子性
注:写端写2000字节后,还想在写3000,这是内存不够大,则处于写阻塞状态,直到内核缓冲去可以存放3000的数据才进行写入
3.非阻塞写管道,如果管道内的剩余空间小于要写入的数据量,返回-1 errno==ESDAIN
代码例子
读端:
#include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <string.h> #include <stdlib.h> int main(int argc , char ** argv) { if(argc < 2) { printf("fifo name....\n"); exit(0); } int fd,len; char buf[1]; fd = open(argv[1],O_RDONLY); len = read(fd,buf,sizeof(buf)); printf("read.c recv:\n"); write(STDOUT_FILENO,buf,len); sleep(10); close(fd); return 0; }
写端:
#include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <string.h> #include <stdlib.h> #define MSG "testMessage..." int main(int argc , char ** argv) { if(argc < 2) { printf("fifo name....\n"); exit(0); } int fd; mkfifo(argv[1],0664); //使用有名管道时,如果没有读端存在,写端尝试打开管道文件阻塞 //如果一个进程以写方式打开管道,当前没有人以读方式打开管道,写打开阻塞 fd = open(argv[1],O_WRONLY); printf("test...\n"); write(fd,MSG,strlen(MSG)); close(fd); return 0; }