FIFO 即有名管道可以在不相关的进程进行数据交换
FIFO的创建
#include<sys/stat.h>
int mkfifo(const char *path,mode_t mode);
成功返回0,出错返回-1
mode参数:与open的参数相同,表示权限,不考虑移植入,可以直接用数据表示。
path:路径
创建一个FIFO之后,我们要用open函数打开它。FIFO的容量是有限制的,定义了一个常量PIPE_BUF,在linux下该值是4096。
下面给出两个历程,一个写历程,一个读历程。
在第一个代码中,我们创建一个FIFO,并将从文件读来的数据,写入其中
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <limits.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <string.h>
int main()
{
const char *file_name="my_fifo";
char *file1="datatxt"; //在这个文件中存储了数据
int res=0;
int pipe_fd=-1;
int data_fd=-1;
char buffer[PIPE_BUF+1]; //PIPE_BUF是一个常量,在linux中是4096
int bytes_sent = 0;
if(access(file_name,F_OK)==-1){ //若管道不存在,就创建它
res=mkfifo(file_name,0777);
if(res!=0)
fprintf(stderr,"can not create fifo %s",file_name);
exit(1);
}
printf("process %d open fifo for write\n",getpid());
pipe_fd=open(file_name,O_WRONLY);
data_fd=open(file1,O_RDONLY);
if(pipe_fd!=-1)
{
int bytes_read=0;
bytes_read=read(data_fd,buffer,PIPE_BUF); //将文件中的数据读到buffer中
buffer[bytes_read]='/0';
while(bytes_read > 0)
{
res = write(pipe_fd, buffer, bytes_read); //往fifo中写数据
if(res == -1)
{
fprintf(stderr, "Write error on pipe\n");
exit(1);
}
bytes_sent += res; //如果文件中数据,大于4096,做个累加,继续读
bytes_read = read(data_fd, buffer, PIPE_BUF);
buffer[bytes_read] = '\0';
}
close(pipe_fd);
close(data_fd);
}else
exit(1);
printf("Process %d finished\n", getpid());
exit(0);
}
在第二个历程中,我们将从上面历程创建的FIFO中读取数据,并将其写入至一个文件。
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <limits.h>
#include <string.h>
int main()
{
const char *fifo_name = "my_fifo";
int pipe_fd = -1;
int data_fd = -1;
int res = 0;
int open_mode = O_RDONLY;
char buffer[PIPE_BUF + 1];
int bytes_read = 0;
int bytes_write = 0;
memset(buffer, '\0', sizeof(buffer)); //清一下缓存
pipe_fd = open(fifo_name, open_mode); //打开我们的有名管道
data_fd = open("DataFormFIFO.txt", O_WRONLY|O_CREAT, 0644); //创建一个文件,打开,只写
if(pipe_fd != -1)
{
do
{
res = read(pipe_fd, buffer, PIPE_BUF); //从管道读取数据到buffer
bytes_write = write(data_fd, buffer, res); //再写到创建的新文件中
bytes_read += res;
}while(res > 0);
close(pipe_fd);
close(data_fd);
}
else
exit(1);
exit(0);
}
FIFO的用途
1)shell命令使用FIFO将数据从一条管道传送到另一条时,无需创建临时文件。
2)客户进程-服务器进程应用程序中,FIFO用作汇聚点,在客户进程和服务器进程之间传送数据。