一.有名管道的介绍
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 32
int 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 32
int 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;
}