一、命名管道FIFO
1.作用范围
对于命名管道FIFO,它可以在不相关的进程间也能相互通信。
2.命名管道可左右用于不相关进程的原因
因为命令管道,提前创建了一个类型为管道的设备文件,在进程里只要使用这个设备文件,就可以相互通信。
3.命名管道的注意点:阻塞与非阻塞
使用open函数打开fifo时,第二个参数有一个非阻塞标志(O_NONBLOCK),有以下几种情况需要注意:
1、不指定O_NONBLOCK时:
① open以只读方式打开FIFO时,要阻塞到某个其他进程为“写”而打开此FIFO,open才解除阻塞。
②open以只写方式打开FIFO时,要阻塞到某个其他进程为“读”而打开此FIFO,open才解除阻塞。
③open以只读、只写方式打开FIFO时会阻塞,调用read函数从FIFO里读数据时read也会阻塞。
④调用write函数向FIFO里写数据,当缓冲区已满时write也会阻塞。
2、指定O_NONBLOCK时
①以只读方式(O_RDONLY | O_NONBLOCK)打开fifo,即便没有"写"进程启动,open也不会阻塞。
②以只写方式(O_WRONLY | O_NONBLOCK)打开fifo,如果没有‘’读”进程启动,open会出错:open: No such device or address。
③read、write读写管道中的数据时不会阻塞。
4.实验验证FIFO的功能和特性
(1)使用的API
创建命名管道:mkfifo(管道名称,权限);
例如:mkfifo("./file",0600);//创建1个名为file的命名管道,其权限为0600;
(2)验证以只读方式打开fifo时(不指定O_NONBLOCK时),open是否会阻塞;
如图,
程序逻辑:
“创建好fifo后,以只读方式打开该fifo(不指定O_NONBLOCK时),打开该fifo后会屏幕输出“open success”;”
程序运行结果:
程序被阻塞了,说明以只读方式打开该fifo,open被阻塞了。
(3)验证“open以只读方式打开FIFO时,要阻塞到某个其他进程为“写”而打开此FIFO,open才解除阻塞。”
如图,编辑了write.c,该c文件的目的是:以“只写”的方式打开名为file的fifo;
程序运行结果:
先运行fiforun(以只读的方式打开fifo,但是open被阻塞了);
接着运行write(以“只写”的方式打开fifo,此时fiforun中的open被解除阻塞);
然后才打印"other process had open fifo"和“open success”
(4)通过fifo实现数据传输
实验目的:创建fifo(不指定O_NONBLOCK);-->fifio.c以只读方式打开fifo(阻塞)--->write.cc中另一个进程以只写的方式打开fifo,解除fifio.c中的open的阻塞状态----->write.c中的进程向fifo写入数据---->fifio.c中利用read从fifo中读取数据;
myfifo.c
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
int main()
{
char buffer[30] = {0};
if((mkfifo("./file",0600) == -1) && errno != EEXIST)
{
printf("mkfifo failed\n");
perror("why");
}
int fd = open("./file",O_RDONLY);
printf("open success\n");
int nread = read(fd,buffer,30);
printf("nread = %d,read_buffer:%s",nread,buffer);
close(fd);
return 0;
}
write.c
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
int main()
{
char buffer_write[30] = {0};
int fd = open("./file",O_WRONLY);
printf("other process had open fifo\n");
printf("please input data to fifo\n");
scanf("%s",buffer_write);
write(fd,buffer_write,strlen(buffer_write));
close(fd);
return 0;
}
~
运行结果:成功实现基于fifo的数据传输
(5)通过fifo实现数据的持续收发
实验目的:一个进程从fifo读数据(在死循环里读),1个进程向fifo写数据(在死循环里写,每1秒写1次);
myfifo.c
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
int main()
{
char buffer[30] = {0};
if((mkfifo("./file",0600) == -1) && errno != EEXIST)
{
printf("mkfifo failed\n");
perror("why");
}
int fd = open("./file",O_RDONLY);
printf("open success\n");
int nread;
while(1)
{
nread = read(fd,buffer,30);
printf("nread = %d,read_buffer:%s",nread,buffer);
nread = 0;
memset(buffer,0,sizeof(buffer));
}
close(fd);
return 0;
}
write.c
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
int main()
{
char buffer_write[30] = "hello\n";
int fd = open("./file",O_WRONLY);
printf("other process had open fifo\n");
printf("please input data to fifo\n");
while(1)
{
write(fd,buffer_write,strlen(buffer_write));
sleep(1);
}
close(fd);
return 0;
}
运行结果: