主要用于没有血缘关系的进程间通信。

特点:
1、半双工,数据在同一时刻只能在一个方向上流动。
2、写入FIFO中的数据遵循先入先出的规则。
3、FIFO所传送的数据是无格式的,这要求FIFO的读出方与写入方必须事先约定好数据的格式,如多少字节算一个消息等。
4、FIFO在文件系统中作为一个特殊的文件而存在,但FIFO中的内容却存放在内存中。
5、管道在内存中对应一个缓冲区。不同的系统其大小不一定相同。
6、从FIFO读数据是一次性操作,数据一旦被读,它就从FIFO中被抛弃,释放空间以便写更多的数据。
7、当使用FIFO的进程退出后,FIFO文件将继续保存在文件系统中以便以后使用。
8、FIFO有名字,不相关的进程可以通过打开命名管道进行通信
2、有名管道的API
#include<sys/types.h>
#include<sys/stat.h>
int mkfifo(const char *pathname, mode_t mode);
功能:
创建有名管道FIFO文件的创建
参数:
pathname:FIFO的路径名+文件名。
mode:mode_t类型的权限描述符。
返回值:
成功:返回 0
失败:如果文件已经存在,则会出错且返回-1
示例代码
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<string.h>
#include<unistd.h>
int main(int argc,char const *argv[])
{
//创建有名管道(保存两个进程 识别相同目录)
mkfifo("my_fifo", 0666);#ifdef WRITE
int fd = open("my_fifo", O_WRONLY);
#endif
#ifdef READ
int fd = open("my_fifo", O_RDONLY);
#endif
if (fd < 0)
{
perror("open");
return 0;
}
#ifdef WRITE
//循环写入数据
while(1){
char buf[128] = "";
printf("请输入需要发送的数据:");
fgets(buf, sizeof(buf), stdin);
buf[strlen(buf) ‐ 1] = 0;
//发送数据
write(fd, buf, strlen(buf));
//退出循环
if (strcmp(buf, "bye") == 0)
break;
}
#endif#ifdef READ
//循环的读取数据
while (1)
{
//接收数据
char buf[128] = "";
read(fd, buf, sizeof(buf));
printf("收到数据位:%s\n", buf);
//退出循环
if (strcmp(buf, "bye") == 0)
break;
}
#endif
close(fd);
return 0;
}gcc a.c -o a -D READ
有名管道读写的特点:
道管开打式方塞阻
1、open以只读方式打开FIFO时,要阻塞到某个进程为写而打开此FIFO
2、open以只写方式打开FIFO时,要阻塞到某个进程为读而打开此FIFO。
3、open以只读、只写方式打开FIFO时会阻塞,调用read函数从FIFO里读数据时read也会阻塞。
4、通信过程中若写进程先退出了,则调用read函数从FIFO里读数据时不阻塞;若写进程又重新运行,则调用read函数从FIFO里读数据时又恢复阻塞。
5、通信过程中,读进程退出后,写进程向命名管道内写数据时,写进程也会(收到SIGPIPE信号)退出。
6、调用write函数向FIFO里写数据,当缓冲区已满时write也会阻塞。
以非阻塞方式打开管道:
1、先以只读方式打开:如果没有进程已经为写而打开一个FIFO, 只读open成功,并且open不阻塞。
2、先以只写方式打开:如果没有进程已经为读而打开一个FIFO,只写open将出错返回-1。
3、read、write读写命名管道中读数据时不阻塞。
4、通信过程中,读进程退出后,写进程向命名管道内写数据时,写进程也会(收到SIGPIPE信号)退出。
注意: open函数以可读可写方式打开FIFO文件时的特点:
1、open不阻塞。
2、调用read函数从FIFO里读数据时read会阻塞。
3、调用write函数向FIFO里写数据,当缓冲区已满时write也会阻塞
网友评论