11、fifo,pipe简介
1、IPC的持久性
1)进程相关的:IPC中数据一直存在到最后一个关联进程关闭时
pipe、fifo等
2)内核相关的IPC:IPC中数据一直存在,除非内核重启或删除
消息队列,共享内存等
3)文件系统相关的IPC:IPC中数据一直存在,除非显式删除
文件
2、管道
匿名管道(pipe):只能用于同一个祖先的进程组
有名管道(fifo):不相关的进程也可以使用
3、匿名管道
int pipe(int filedes[2]);
fildes[0] 用于从管道中读取数据
fildes[1] 用于将数据写入管道
不需要open,直接read/write 等系统调用
系统自动删除,进程不需要考虑
示例

#include "stdio.h"
#include "stdlib.h"
#include "unistd.h"
#include "string.h"
int main(void)
{
int n, fd[2];
pid_t pid;
char line[512];
memset(line, 0, 512);
if (pipe(fd) < 0)
{
printf("pipe error");
}
if ((pid = fork()) < 0)
{
printf("fork error");
}
else if (pid > 0)
{
/* parent */
close(fd[0]);
write(fd[1], "hello\n", 13);
}
else
{
/* child */
close(fd[1]);
n = read(fd[0], line, 215);
printf("%s", line);
}
}
4、有名管道
int mkfifo(const char *pathname, mode_t mode);
pathname等参数和open类似
需要open,open必须只能是只读或只写。
open阻塞模式:阻塞到有进程以相对应方式打开相同的fifo。
open非阻塞式:只读打开立刻返回;只写时,如果没有对应的进程已经只读打开相同的fifo,返回错误。
open之后才能read/write,操作与文件类似。
FIFO必须显式删除(调用unlink),但fifo中保存的数据是进程相关的
示例

#include "stdio.h"
#include "stdlib.h"
#include "unistd.h"
#include "sys/types.h"
#include "sys/stat.h"
#include "fcntl.h"
#include "string.h"
#define MAXLINE 256
int main(void)
{
int rfd, wfd;
pid_t pid;
char line[MAXLINE];
if (mkfifo("./fifo1", 0666) < 0)
{
printf("mkfifo error");
}
if ((pid = fork()) < 0)
{
printf("fork error");
}
else if (pid > 0)
{
/* parent */
if((wfd = open("./fifo1", O_WRONLY)) > 0 )
{
write(wfd, "hello\n", 13);
close(wfd);
}
}
else
{ /* child */
if((rfd = open("./fifo1", O_RDONLY)) > 0 )
{
int n = read(rfd, line, MAXLINE);
printf("%s", line);
close(rfd);
}
}
}
5、写管道时,常数PIPE_BUF(一般为4096)规定了内核中管道缓存器的大小,如果写小于或等于PIPE_BUF大小的数据进入不会被打断,但大于PIPE_BUF的数据可能会被其他进程打断
关闭所有的写端,read返回0
关闭所有的读端,write会产生SIGPIPE信号
不能lseek,否则返回ESPIPE错误
参考
【1】 http://linchunai1212.blog.163.com/blog/static/35112143201111361543958/
【2】 http://www.linuxidc.com/Linux/2010-09/28317.htm
【3】 http://www.dzsc.com/data/html/2009-9-10/78618.html
【4】 http://blog.csdn.net/MONKEY_D_MENG/article/details/5570468