目录
有名管道的特点
-
有名管道可以使非亲缘的两个进程互相通信
-
通过路径名来操作,在文件系统中可见,但内容存放在内存中
-
文件IO来操作有名管道
-
遵循先进先出规则
-
不支持leek操作
-
单工读写
-
有名管道打开时有可能会阻塞
有名管道的创建
#include <unistd.h>
#include <fcntl.h>
int mkfifo(const char *path, mode_t mode);
成功时返回0,失败时返回EOF
path创建的管道文件路径
mode 管道文件的权限,如0666
有名管道的举例
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
int main(){
int re;
int fd;
char buf[32];
re = mkfifo("/myfifo",0666);
if(re<0){
perror("mkfifo");
//return 0;
}
fd = open("/myfifo",O_WRONLY|O_NONBLOCK);
if(fd<0){
perror("open");
return 0;
}
printf("after open\n");
while(1){
fgets(buf,32,stdin);
write(fd,buf,strlen(buf));
}
}
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
int main(){
int re;
int fd;
char buf[32];
/*
re = mkfifo("/myfifo",0666);
if(re<0){
perror("mkfifo");
return 0;
}
*/
fd = open("/myfifo",O_RDONLY);
if(fd<0){
perror("open");
return 0;
}
printf("after open\n");
while(1){
re=read(fd,buf,32);
if(re>0){
printf("read fifo=%s\n",buf);
}else if(re==0){
exit(0);
}
}
}
无名管道的特点
- 只能用于具有亲缘关系的进程之间的通信
- 单工的通信模式,具有固定的读端和写端(一端读,一端写(程序实现设计好)。)
- 无名管道创建时会返回两个文件描述符,分别用于读写管道
无名管道的创建--pipe
#include <unistd.h>
int pipe(int pfd[2]);
成功时返回0,失败时返回EOF
pfd包含两个元素的整形数组,用来保存文件描述符
pfd[0]用于读管道;pfd[1]用于写管道
无名管道的通信
无名管道的举例
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
int main(){
int pfd[2];
int re;
char buf[20]={0};
pid_t pid;
re = pipe(pfd);
if(re<0){
perror("pipe");
return 0;
}
printf("%d,%d\n",pfd[0],pfd[1]);
pid = fork();
if(pid<0){
perror("fork");
return 0;
}else if(pid>0){
close(pfd[0]);
// close(pfd[1]);
int j=0;
while(1){
j++;
strcpy(buf,"hhahahahah");
for(int i=0;i<1000;i++){
write(pfd[1],buf,strlen(buf));
}
printf("write %d times\n",j);
sleep(1);
}
}else{
close(pfd[1]);
// close(pfd[0]);
sleep(30000);
exit(0);
while(1){
re=read(pfd[0],buf,20);
if(re>0){
printf("read pipe=%s\n",buf);
}else if(re==0){
printf("re=0\n");
}
}
}
}
无名管道的读写特性
- 读管道
1. 管道中有数据,read返回实际读到的字节数。
2. 管道中无数据:
(1) 管道写端被全部关闭,read返回0 (相当于读到文件结尾)
(2) 写端没有全部被关闭,read阻塞等待(不久的将来可能有数据递达,此时会让出cpu)
- 写管道
1. 管道读端全部被关闭, 进程异常终止(也可使用捕捉SIGPIPE信号,使进程不终止)
2. 管道读端没有全部关闭:
(1) 管道已满,write阻塞。(管道大小64K)
(2)管道未满,write将数据写入,并返回实际写入的字节数。