有名管道(fifo)
特点:区别于无名管道在于其科以用于没有血缘关系的进程通讯,其更像文件,具有文件名,存放路径等,利用有名管道操作后,我们可以再相应的目录下找到他。
用法:通过mkfifo创建有名管道,然后可以像操作文件一样open()\close(),read()/write()。
函数参考:
int mkfifo(const char *pathname, mode_t mode)
对于读操作:
(1)若该管道是阻塞打开,且当前FIFO内没有数据,则对读进程而言将一直阻塞到有数据写入。
(2)若该管道是非阻塞打开,则不论FIFO内是否有数据,读进程都会立即执行读操作。即如果FIFO内没有数据,则读函数将立刻返回0。
对于写操作:
(1)若该管道是阻塞打开,一直阻塞直到数据可写入;
(2)若该管道是非阻塞打开,若不能全部写入,则写入部分或报错。
举例说明:
功能:创建一个有名管道实现两个进程间通讯。
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define FIFO "/home/smb/myfifo"
int main(int argc,char** argv)
{
char buf[100];
int fd;
int nread;
/* 打开管道 */
fd=open(FIFO,O_RDONLY|O_NONBLOCK,0);
if(fd==-1)
{
perror("open");
exit(1);
}
while(1)
{
memset(buf,0,sizeof(buf));
if((nread=read(fd,buf,100))==-1)
{
if(errno==EAGAIN)
printf("no data yet\n");
}
printf("read from FIFO:%s\n",buf);
sleep(1);
}
close(fd); }
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define FIFO_SERVER "/home/smb/myfifo"
int main(int argc,char** argv)
{
int fd;
char w_buf[100];
int nwrite;
/*创建有名管道*/
if((mkfifo(FIFO_SERVER,O_CREAT|O_EXCL|O_RDWR)<0)&&(errno!=EEXIST))
printf("cannot create fifoserver\n");
/*打开管道*/
fd=open(FIFO_SERVER,O_RDWR|O_NONBLOCK,0);
if(fd==-1)
{
perror("open");
exit(1);
}
/*入参检测*/
if(argc==1)
{
printf("Please send something\n");
exit(-1);
}
strcpy(w_buf,argv[1]);
/* 向管道写入数据 */
if((nwrite=write(fd,w_buf,100))==-1)
{
if(errno==EAGAIN)
printf("The FIFO has not been read yet.Please try later\n");
}
else
printf("write to the FIFO: %s\n",w_buf);
close(fd); //关闭管道
return 0;
}
运行结果:
在一个进程中写入:
另一个进程会接受如下:
同时我们可以看到管道文件: