有名管道FIFO是Linux系统中的一个特殊文件。当使用FIFO的进程退出以后,FIFO文件依然保存在系统中,方便下一次的使用。有名管道可以创建名称,因此,不同的进程之间可以通过操作FIFO文件进行通信。
通过函数:int mkfifo(const char *pathname,mode_t mode)来创建有名管道文件。有名管道依然是一种文件,因此可以通过open打开文件,并且通过read和write函数来操作文件中的内容。
两个进程之间使用有名管道通信的代码如下:
/*利用有名管道实现两个没有关系的进程之间的通信,
在此部分写入数据*/
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <fcntl.h>
int main()
{
//判断管道是否存在
int res = access("test",F_OK);
if(res == -1)
{
printf("管道不存在,正在创建管道:\n");
//创建管道
int ret = mkfifo("test",0664);
if(ret == -1)
{
perror("mkfifo");
exit(0);
}
}
//以只写的方式打开管道
int fd = open("test",O_WRONLY);
//int fd1=open("test",O_RDONLY);
if(fd == -1)
{
perror("open");
exit(0);
}
for(int i = 0;i < 100;i++ )
{
char buf[1024] ;
sprintf(buf,"hello \n%d",i);
printf("write data : %s\n",buf);
int len = write(fd,buf,strlen(buf));
/* char buf1[1024];
int len1=read(fd1,buf1,strlen(buf1));
printf("buf:%s",buf1);
*/
printf("len:%d \n",len);
sleep(1);
}
close(fd); //关闭管道文件
return 0;
}
/*利用有名管道实现两个没有关系的进程之间的通信,
在此部分读取数据*/
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <fcntl.h>
int main()
{
//以只读的方式打开有名管道文件
int fd = open("test",O_RDONLY);
if(fd == -1)
{
perror("open");
exit(0);
}
while(1)
{
char buf[1024] ={0};
int len = read(fd,buf,sizeof(buf));
if(len == 0)
{
printf("连接断开...\n");
break;
}
printf("read data:%s \n",buf);
//memset(buf,0,strlen(buf));
sleep(1);
}
close(fd); //关闭管道文件
return 0;
}
运行结果:
5.总结:有名管道FIFO是一种文件系统,因此进程之间的通信时,和操作普通文件的过程是一样的,使用相同的文件操作函数。在实验的过程中发现,read()函数读取数据时,传入的读取的字节数大小,不能使用strlen(),而是得使用sizeof()。strlen是求解数组中字符的长度,遇到“\0”才会返回长度,sizeof()是直接统计数组的字节的数量。当使用stelen作为read()的读取字节数大小时,会导致write失败,读取到的字节数为0。这个小问题在实验的过程中困扰了我很久,希望以后能够多多注意这样的细节问题。