一、概述 进程之间通过管道来进行通讯是一种常用的方法,顾名思义,管道就是一端进(写)一端出(读)的FIFO队列,这个队列由内核管理,有一定大小(一般是4k),有文章上提到,如果需要修改该缓存区,需要重新编译内核(修改Linux/limits.h里PIPE_BUF的定义)。
需要明确的是,虽然管道在理论上是双向的,但实际应用时,为避免复杂,都单向来用,需要双向通讯时,采用两个管道进行。
具有亲缘关系的进程可以采用匿名管道,没有亲缘关系的进程采用命名管道,本文以命名管道为主进行讨论。
二、有关的管道函数 创建管道
int mkfifo(const char * pathname,mode_t mode);
打开管道
int open(const char pathname,int oflag,… / mode_t mode */);
读写
int read(int handle, void *buf, int nbyte)
int write(int handle, void *buf, int nbyte)
关闭
Close(int handle)
这些函数都比较简单,不做深入说明。
三、阻塞和非阻塞 同文件、网络等一样,通过在open方法中是否设置O_NONBLOCK标志,管道操作有两种运行方式:阻塞和非阻塞模式。
- 阻塞模式 阻塞模式下,无论是读端或写端,如果对方没有打开,open都会阻塞,而write和read的行为见表1。该表总结的场景是读端和写端都已顺利打开,双方进程调用write或read发生的情况。
表1 阻塞模式下write和read行为
写端进程
读端进程
关闭
管道中还有数据
可继续读取
未关闭
管道中没有数据
不阻塞,返回0
未关闭
管道中没有数据
阻塞
管道写满,阻塞
写数据,收到信号SIGPIPE,导致进程异常终止
关闭
2.非阻塞模式 无论是读端或写端,open不会阻塞。在双方都顺利打开后,即使没有数据,read不会阻塞,返回-1,errno置为11。write也不会阻塞。
四、测试代码 下面代码分读端和写端,属于两个进程,分别编译运行。写端写十次后退出,读端如果读到的数据是“exit”,退出。 写数据端
[cpp] view plain copy
#include
int i;
for(i=0;i<10;i++)
{
fgets(buf, 100, stdin);
num = strlen(buf);
num=write(fifo_fd, buf, num);
if(num == -1)
printf(“Error[%d] when writing data into named pipe”,errno);
else
printf(“Writed %d chars into named pipe:%s\n”, num, buf);
}
close(fifo_fd);
return 0;
}
读数据端
[cpp] view plain copy
#include
本文转载自http://blog.csdn.net/guxch/article/details/6828452 仅供学习参考使用