通过命令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;
}