命名管道是一种实际存在的FIFO文件,用于不同进程之间,命名管道进程间打开同一个FIFO文件,进行数据传递。
mkfifo函数:创建一个命名管道
int mkfifo(const char *filename,mode_t mode);
测试源码:
1、使用函数创建一个比较大的文件
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
void copy_file(FILE *,char *);
int main(int argc, char *argv[])
{
FILE *fp;
long int i = 100000;
char buf[] = "This is a mkfifo test!\n";
char *file = "data.txt";
printf("begin!\n");
if((fp = fopen(file,"a+")) == NULL )
{
printf("can't open %s\n",file);
return -1;
}
while(i--)
{
copy_file(fp,buf);
}
fclose(fp);
printf("over!\n");
return 0;
}
void copy_file(FILE *fp,char *buf)
{
char c;
int i,j;
j = 0;
i = strlen(buf)-1;
while(i--)
{
putc(buf[j],fp);
j++;
}
putc('\n',fp);
}
2、创建写命名管道文件
测试源码:
#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(int argc,char *argv[])
{
const char *fifo_name = "my_fifo";
char *file = "data.txt";
int pipe_fd = -1;
int data_fd = -1;
int res = 0;
int bytes_sent = 0;
char buffer[PIPE_BUF + 1];
if(access(fifo_name, F_OK) == -1)
{
//管道文件不存在
//创建命名管道
res = mkfifo(fifo_name, 0777);
if(res != 0)
{
fprintf(stderr, "Can not create fifo %s\n", fifo_name);
exit(EXIT_FAILURE);
}
}
printf("Process %d opening FIFO O_WRONLY\n", getpid());
//以只写阻塞方式打开FIFO文件,以只读方式打开数据文件
pipe_fd = open(fifo_name, O_WRONLY);
data_fd = open(file, O_RDONLY);
printf("Process %d result %d\n", getpid(), pipe_fd);
if(pipe_fd != -1)
{
int bytes_read = 0;
//向数据文件读取数据
bytes_read = read(data_fd, buffer, PIPE_BUF);
buffer[bytes_read] = '\0';
while(bytes_read > 0)
{
//向FIFO文件写数据
res = write(pipe_fd, buffer, bytes_read);
if(res == -1)
{
fprintf(stderr, "Write error on pipe\n");
exit(EXIT_FAILURE);
}
//累加写的字节数,并继续读取数据
bytes_sent += res;
bytes_read = read(data_fd, buffer, PIPE_BUF);
buffer[bytes_read] = '\0';
}
close(pipe_fd);
close(data_fd);
}
else
exit(EXIT_FAILURE);
printf("Process %d finished\n", getpid());
exit(EXIT_SUCCESS);
}
3、创建读管道文件
#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(int argc,char *argv[])
{
const char *fifo_name = "my_fifo";
int pipe_fd = -1;
int data_fd = -1;
int res = 0;
char buffer[PIPE_BUF + 1];
int bytes_read = 0;
int bytes_write = 0;
//清空缓冲数组
memset(buffer, '\0', sizeof(buffer));
printf("Process %d opening FIFO O_RDONLY\n", getpid());
//以只读阻塞方式打开管道文件,注意与fifowrite.c文件中的FIFO同名
pipe_fd = open(fifo_name, O_RDONLY);
//以只写方式创建保存数据的文件
data_fd = open("DataFormFIFO.txt", O_WRONLY|O_CREAT, 0644);
printf("Process %d result %d\n",getpid(), pipe_fd);
if(pipe_fd != -1)
{
do
{
//读取FIFO中的数据,并把它保存在文件DataFormFIFO.txt文件中
res = read(pipe_fd, buffer, PIPE_BUF);
bytes_write = write(data_fd, buffer, res);
bytes_read += res;
}while(res > 0);
close(pipe_fd);
close(data_fd);
}
else
exit(EXIT_FAILURE);
printf("Process %d finished, %d bytes read\n", getpid(), bytes_read);
exit(EXIT_SUCCESS);
return 0;
}
4、编译每一个源文件,生成ELF文件。
5、创建一个用于测试的文本文件:
./test_creat
6、运行写管道文件,让其在后台运行
./test_write
7、运行读管道文件
./test_read
8、比较新的文件与原来的文件
diff data.txt DataFormFIFO.txt