liux 命名管道fifo

无名管道pipe 和 命名管道fifo 区别:
pipe用于父子进程间通信;fifo用于系统中任何两个进程间通信

*int mkfifo( const char pathname, mode_t mode)
用于创建管道。
命名管道其本质是 文件,但是
mkfifo myfifo
ls -al 发现管道的文件myfifo 始终大小为0

写入myfifo文件
echo “hello myfriend” > myfifo &
[1] 9273
读出myfifo文件
hello myfriend
[1]+ 已完成 echo “hello myfriend” > myfifo
一旦管道被读取或“耗干”,该管道就清空了

pathname : fifo文件名
mode: 属性 (同文件操作的属性一样)
返回值:0表示创建成功,-1表示创建失败。
一旦创建一个fifo,就可用open打开,也可以用到一般的文件访问函数 close read都可以用在fifo上。

对于 打开FIFO ,非阻塞标志(O_NONBLOCK)

  1. 使用O_NONBLOCK:访问要求无法满足时,不阻塞,立刻出错返回,errno是ENXIO
  2. 没有使用O_NONBLOCK:访问要求无法满足时,进程阻塞。例如 读取空的FIFO,会导致进程阻塞。

值得注意的是,命名管道的内容驻留在内存中而不是被写到硬盘上。数据内容只有在输入输出端都打开时才会传送。用户可以在管道的输出端打开之前向管道多次写入。通过使用命名管道,用户可以创建一个进程写入管道并且另外一个进程读取管道的流程,而不用关心协调二者时间上的同步。

命名管道一旦被读取之后,管道中的内容就没有了。
fifo_read.c

#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#define FIFO_SERVER “/tmp/myfifo”

void main(int argc,char *argv[])
{
int fd;
char r_buf[100];
int nread;
int status;

/* 创建管道 */
status = mkfifo(FIFO_SERVER,O_CREAT|O_EXCL);//O_EXCL这个再有O_CREAT才能生效,如果O_CREAT|O_EXCL两个同时存在的话,文件存在,则返回错误信息EEXIST,文件不存在,则创建,返回成功,此标志用于检测文件是否存在。
if((status == -1) && (errno != EEXIST))
{
	printf("cannot creat fifoserver\n");
}
printf("preparing for reading bytes...\n");
memset(r_buf,0,sizeof(r_buf));

/* 打开管道 */
fd = open(FIFO_SERVER,O_RDONLY|O_NONBLOCK,0);
if(-1 == fd)
{
	perror("open");
	exit(1);
}
while(1)
{
	memset(r_buf,0,100);
	nread = read(fd,r_buf,100);
	if(-1 == nread)
	{

/* EAGAIN这个错误经常在非阻塞操作中,例如fifo中,如果你连续read没有数据可读,此时程序不会阻塞起来等待数据准备就绪,read函数就会返回一个错误EAGAIN,提示你应用程序现在没有数据可读,稍后再试*/
if(errno == EAGAIN)
{
printf(“no data writed yet\n”);
}
}
printf(“read %s from FIFO\n”,r_buf);
sleep(1);
}
pause(); /暂停,等待信号/
unlink(FIFO_SERVER);/删除文件/
}

fifo_write.c
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#define FIFO_SERVER “/tmp/myfifo”

void main(int argc,char *argv[])
{
int fd;
char w_buf[100];
int nwrite;

/* 打开管道 */
fd = open(FIFO_SERVER,O_WRONLY|O_NONBLOCK,0);
if(-1 == fd)
{
	perror("open");
	exit(1);
} 

if(argc == 1 )
{
	printf("please send something \n");
	exit(-1);
}
memset(w_buf,0,sizeof(w_buf));
strncpy(w_buf,argv[1],50);

/* 向管道内写入数据 */
nwrite = write(fd,w_buf,100);
if(-1 == nwrite)
{
	/* EAGAIN这个错误经常在非阻塞操作中,例如fifo中,如果你连续read没有数据可读,此时程序不会阻塞起来等待数据准备就绪,read函数就会返回一个错误EAGAIN,提示你应用程序现在没有数据可读,稍后再试*/
	if(errno == EAGAIN)
	printf("the FIFO has not been read yet,please try later\n");		
}	
else
	printf("write %s to the FIFO\n",w_buf);

}

fifo_read.c执行结果是
./fiforead
read from FIFO
read from FIFO
read from FIFO
read from FIFO
read from FIFO
read from FIFO
read 12345 from FIFO
read from FIFO
read from FIFO
read from FIFO
read from FIFO

fifo_write.c执行结果是
./fifowrite 12345
write 12345 to the FIFO

当管道写入,经过读出后,管道里面的数据就空了。

猜你喜欢

转载自blog.csdn.net/shi18363123750/article/details/82950398