有名管道:
无名管道只能用于有亲缘关系的进程间通信。
因此提出有名管道(也叫FIFO文件),以实现无亲缘关系进程间的通信。
不同于无名管道,有名管道FIFO文件的形式存在于文件系统,与一个路径名关联,因此无亲缘关系的进程也可以通过该路径互相通信。
有名管道特点:
(1)FIFO文件属于文件系统中的特殊文件,但其内容存放于内存;
(2)FIFO进程退出后,FIFO文件继续保留在文件系统中供后续使用;
(3)可实现无亲缘关系进程间的通信。
(1)mkfifo函数
#include<sys/types.h>
#include<sys/stat.h>
int mkfifo(const char* pathname, mode_t mode);
/*
功能:
以mode权限创建有名管道pathname
参数:
pathname:创建FIFO文件的路径名,相对路径、绝对路径都可。
mode:文件的权限,与open函数的mode参数一样。
返回值:
成功:0
失败:若文件存在则返回-1
*/
mkfifo示例:
#include<string.h>
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/stat.h>
int main(int argc, const char* argv[]) {
int ret = -1;
ret = mkfifo("fifotest", 0644); // 创建权限为0644的有名管道
if (-1 == ret) {
perror("mkfifo");
return 1;
}
printf("fifo file created.\n");
return 0;
}
创建成功。
(2)有名管道的读写
(1)有名管道可用open打开,用read、write、close、unlink等操作,但同样不可lseek;
(2)一个以只写方式打开管道的进程会被阻塞,直到另一个进程以只读方式打开该管道;
(3)一个以只读方式打开管道的进程会被阻塞,直到另一个进程以只写方式打开该管道;
有名管道读写示例:
写管道程序:
#include<string.h>
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<unistd.h>
#include<fcntl.h>
#define SIZE 128
int main(int argc, const char* argv[]) {
int i = 0;
int ret = -1;
int fd = -1;
char buf[SIZE];
// 1. 以只写的方式打开一个管道文件
fd = open("./fifotest", O_WRONLY);
if (-1 == fd) {
perror("open");
return 1;
}
printf("writeonly open success.\n");
// 2. 写管道
while (1) {
memset(buf, 0, SIZE);
sprintf(buf, "hello %d", i++);
ret = write(fd, buf, strlen(buf));
if (ret <= 0) {
perror("write");
break;
}
printf("写入%d个字节.\n", ret);
sleep(1);
}
// 3. 关闭FIFO文件
close(fd);
return 0;
}
读管道程序:
#include<string.h>
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<unistd.h>
#include<fcntl.h>
#define SIZE 128
int main(int argc, const char* argv[]) { // 读管道
int ret = -1;
int fd = -1;
char buf[SIZE];
// 1. 以只读的方式打开一个管道文件
fd = open("fifotest", O_RDONLY);
if (-1 == fd) {
perror("open");
return 1;
}
printf("readonly open success.\n");
// 2. 循环读管道
while (1) {
memset(buf, 0, SIZE);
ret = read(fd, buf, SIZE);
if (ret <= 0) {
perror("read");
break;
}
printf("读出buf:%s\n", buf);
}
// 3. 关闭FIFO文件
close(fd);
return 0;
}
运行结果: