1. FIFO与PIPE的不同
a. mkfifo只是创建了一个fifo文件,还需要open之后才可以调用read/write
PIPE后可以直接调用read/write
b. FIFO退出时要调用unlink去删除文件,否则下次调用mkfifo时会失败,
PIPE没有创建文件,就谈不上删除不删除了
1.1 mkfifo后open
-
打开FIFO文件和普通文件的区别有2点:
-
第一个是不能以O_RDWR模式打开FIFO文件进行读写操作。这样做的行为是未定义的。
-
因为我们通常使用FIFO只是为了单向传递数据,所以没有必要使用这个模式。
-
如果确实需要在程序之间双向传递数据,最好使用一对FIFO或管道,一个方向使用一个。或者采用先关闭在重新打开FIFO的方法来明确改变数据流的方向。
-
第二是对标志位的O_NONBLOCK选项的用法。
-
使用这个选项不仅改变open调用的处理方式,还会改变对这次open调用返回的文件描述符进行的读写请求的处理方式。
-
O_RDONLY、O_WRONLY和O_NONBLOCK标志共有四种合法的组合方式:
-
flags=O_RDONLY:open将会调用阻塞,除非有另外一个进程以写的方式打开同一个FIFO,否则一直等待。
-
flags=O_WRONLY:open将会调用阻塞,除非有另外一个进程以读的方式打开同一个FIFO,否则一直等待。
-
flags=O_RDONLY|O_NONBLOCK:如果此时没有其他进程以写的方式打开FIFO,此时open也会成功返回,此时FIFO被读打开,而不会返回错误。
-
flags=O_WRONLY|O_NONBLOCK:立即返回,如果此时没有其他进程以读的方式打开,open会失败打开,此时FIFO没有被打开,返回-1。
-
这部分内容这转自 《【Linux】进程间通信-命名管道FIFO》
http://blog.csdn.net/xiajun07061225/article/details/8471777
2.FIFO的代码
-
#include <stdio.h>
-
#include <stdlib.h>
-
#include <unistd.h>
-
#include <sys/types.h>
-
#include <sys/stat.h>
-
#include <string.h>
-
#include <fcntl.h>
-
-
#define FIFO1 "/tmp/fifo1"
-
#define FIFO2 "/tmp/fifo2"
-
-
//child--->fifo1-->parent
-
//child<---fifo2<--parent
-
void parent_process(int readfd, int writefd);
-
void child_process(int readfd, int writefd);
-
-
int main ( int argc, char *argv[] )
-
{
-
int readfd, writefd;
-
pid_t childpid;
-
//int mkfifo(const char *pathname, mode_t mode);
-
if(mkfifo(FIFO1,0666) < 0) //后面的0666就是创建/tmp/fifo1的文件权限--> prw-rw-r--
-
{
-
unlink(FIFO1);
-
perror("mkfifo1 error");
-
return -1;
-
}
-
-
if(mkfifo(FIFO2,0666) < 0)
-
{
-
unlink(FIFO2);
-
perror("mkfifo2 error");
-
return -1;
-
}
-
-
printf("next fork\n");
-
if( (childpid = fork()) < 0)
-
{
-
perror("fork error\n");
-
return -1;
-
} else if(childpid==0) //child
-
{
-
printf("child\n");
-
readfd = open(FIFO1, O_RDONLY, 0); //对FIFO1-->read
-
writefd = open(FIFO2, O_WRONLY, 0); //对FIFO2-->write
-
printf("child process\n"); //child与parent的read/write顺序一定不能颠倒
-
child_process(readfd, writefd); //否则会一直阻塞
-
exit(0);
-
} else if(childpid > 0) //parent
-
{
-
printf("parent\n");
-
writefd = open(FIFO1, O_WRONLY, 0); //对FIFO1-->write
-
readfd = open(FIFO2, O_RDONLY, 0); //对FIFO2-->read
-
-
printf("parent process\n");
-
parent_process(readfd, writefd);
-
-
printf("next waitpid\n");
-
waitpid(childpid, NULL, 0);
-
printf("waitpid over\n");
-
close(readfd);
-
close(writefd);
-
unlink(FIFO1);
-
unlink(FIFO2);
-
}
-
return EXIT_SUCCESS;
-
}
-
-
void parent_process(int readfd, int writefd)
-
{
-
char buf[1024];
-
printf("next parent read\n");
-
read(readfd, buf, sizeof(buf));
-
printf("parent read_buf=%s",buf);
-
-
sleep(1);
-
write(writefd, "hello,world222\n",strlen("hello,world222\n")+1);
-
}
-
-
void child_process(int readfd, int writefd)
-
{
-
char buf[1024];
-
sleep(1);
-
printf("next child write\n");
-
write(writefd, "hello,world111\n",strlen("hello,world111\n")+1);
-
-
printf("next child read\n");
-
read(readfd, buf, sizeof(buf));
-
printf("child read_buf=%s",buf);
-
}
注意: fork后若child先执行,read_FIFO1
child: read_FIFO1 阻塞直到parent有write_FIFO1
parent: write_FIFO1
注意: fork后若parent先执行,read_FIFO1
parent: write_FIFO1 阻塞直到child有read_FIFO1
child: read_FIFO1
3.改进版
在mkfifo之前需要先检查文件是否存在,若存在要先删除才可以mkfifo
-
#include <stdio.h>
-
#include <stdlib.h>
-
#include <unistd.h>
-
#include <sys/types.h>
-
#include <sys/stat.h>
-
#include <string.h>
-
#include <fcntl.h>
-
-
#define FIFO1 "/tmp/fifo1"
-
#define FIFO2 "/tmp/fifo2"
-
-
//child--->fifo1-->parent
-
//child<---fifo2<--parent
-
void parent_process(int readfd, int writefd);
-
void child_process(int readfd, int writefd);
-
-
int main ( int argc, char *argv[] )
-
{
-
int readfd, writefd;
-
pid_t childpid;
-
//1. del existed FIFO
-
if(0 == access(FIFO1, F_OK))
-
{
-
printf("FIFO1 exist\n");
-
unlink(FIFO1);
-
}
-
if(0 == access(FIFO2, F_OK))
-
{
-
printf("FIFO2 exist\n");
-
unlink(FIFO2);
-
}
-
//2. then mkfifo
-
if(mkfifo(FIFO1,0666) < 0)
-
{
-
unlink(FIFO1);
-
perror("mkfifo1 error");
-
return -1;
-
}
-
-
if(mkfifo(FIFO2,0666) < 0)
-
{
-
unlink(FIFO2);
-
perror("mkfifo2 error");
-
return -1;
-
}
-
//3.fork
-
printf("next fork\n");
-
if( (childpid = fork()) < 0)
-
{
-
perror("fork error\n");
-
return -1;
-
} else if(childpid==0) //child
-
{
-
printf("child\n");
-
readfd = open(FIFO1, O_RDONLY, 0);
-
writefd = open(FIFO2, O_WRONLY, 0);
-
printf("child process\n");
-
child_process(readfd, writefd);
-
exit(0);
-
} else if(childpid > 0) //parent
-
{
-
printf("parent\n");
-
writefd = open(FIFO1, O_WRONLY, 0);
-
readfd = open(FIFO2, O_RDONLY, 0);
-
-
printf("parent process\n");
-
parent_process(readfd, writefd);
-
-
printf("next waitpid\n");
-
waitpid(childpid, NULL, 0);
-
printf("waitpid over\n");
-
close(readfd);
-
close(writefd);
-
unlink(FIFO1);
-
unlink(FIFO2);
-
}
-
return EXIT_SUCCESS;
-
}
-
-
void parent_process(int readfd, int writefd)
-
{
-
char buf[1024];
-
printf("next parent read\n");
-
read(readfd, buf, sizeof(buf));
-
printf("parent read_buf=%s",buf);
-
-
sleep(1);
-
write(writefd, "hello,world222\n",strlen("hello,world222\n")+1);
-
}
-
-
void child_process(int readfd, int writefd)
-
{
-
char buf[1024];
-
sleep(1);
-
printf("next child write\n");
-
write(writefd, "hello,world111\n",strlen("hello,world111\n")+1);
-
-
printf("next child read\n");
-
read(readfd, buf, sizeof(buf));
-
printf("child read_buf=%s",buf);
-
}
先删除fifo文件后再mkfifo
阅读(1426) | 评论(0) | 转发(0) |