一.有名管道的介绍
1.特点:
①.对应管道文件,可用于任意进程之间进行通信。
②.打开管道时可指定读写方式(打开管道时可指定读写方式)。
③.通过文件IO操作,内容存放在内存中。
2.读有名管道
(1).写端存在时
①.管道内有数据时,读端调用read()函数,返回值是实际读到的字节数。
②.管道内没有数据时,读端调用read()会阻塞等待,直到管道内有数据。
(3).写端不存在时
①.管道内有数据时,读端调用read()函数,返回值是实际读到的字节数。
②.管道内没有数据时,读端调用read()函数,会立刻返回0。
3.写有名管道
(1).读端存在(有进程可以读管道)
①.有空间时,write()返回实际写入的字节数。
②.空间不足时,假设管道内剩余128个字节空间可以写入,但是write()里面要写256 个字节,进程会先写入128个字节,等到(写操作进行阻塞)管道有空间了再继续写入。
(2).读端不存在(没有进程可以读管道)
①.管道会断裂,即写管道的进程会被信号结束。
二.有名管道C函数
1.有名管道创建 - mkfifo
功能:
创建有名管道。
成功时返回(0),失败时返回(EOF)。
创建好有名管道后,就可通过write、read函数进行操作。
参数:
path :要创建的有名管道的路径
mode :指定管道文件的权限,0777是最大权限
int mkfifo(const char *path,mode_t mode);
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>int main(void)
{/* 创建有名管道 */if(0 > mkfifo("myfifo",0666)){perror("mkfifo error");exit(-1);}return 0;
}
可以看到:创建有名管道后,可以在路径下看到管道文件
三.有名管道读写 - 示例
进程A:循环从键盘输入并写入有名管道myfifo,输入quit时退出
进程B:循环统计进程A每次写入管道myfifo的字符串的长度
1.流程图
2.create_fifo.c
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>int main(void)
{/* 创建有名管道 */if(0 > mkfifo("myfifo",0666)){perror("mkfifo error");exit(-1);}return 0;
}
3.write_fifo.c
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>#define N 32int main(void)
{int pfd;char buf[N];/* 以只写方式打开有名管道文件 */pfd = open("myfifo",O_WRONLY);if(0 > pfd){perror("open error");exit(-1);}printf("myfifo is opened\n");while(1){fgets(buf,N,stdin);/* 输入quit退出 */if(strcmp(buf,"quit\n") == 0)break;/* 若读端消失,则此进程会被信号结束 */write(pfd,buf,N); }close(pfd);return 0;
}
4.read_fifo.c
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>#define N 32int main(void)
{int pfd;char buf[N];/* 以只读方式打开有名管道文件 */pfd = open("myfifo",O_RDONLY);if(0 > pfd){perror("open error");exit(-1);}printf("myfifo is opened\n");/* 若写端消失了,则read返回0,退出循环 */while(0 < read(pfd,buf,N)){printf("the length of string is %ld\n",strlen(buf));}close(pfd);return 0;
}