管道文件为内存及文件,没有名称(匿名管道)
如何让两个进程看到同一个管道文件?
通过fork创建子进程完成。
匿名管道可以用于父子进程之间的通信。
匿名管道是一个固定大小的缓冲区,写端写满后就会阻塞,等待读取。
管道的特征:
操作系统间接提供内存空间。(管道的大小是有限的)
管道读写的特征:
读快写慢:
如果管道中没有了数据,读端在读,默认会直接阻塞当前正在读取的进程。
读慢写快:
管道是一个固定大小的缓冲区。
写端写满的时候会阻塞,等对方进行读取。
管道读取得时候不是按行读取,而是按指定大小读取的。大小满足后一次性读取大量数据。
写关闭继续读
将管道中数据读取完毕后,结束进程。
读关闭继续写:
管道是单向通信的,这样的行为没有意义。
OS会终止写端,会给写端发信号,终止写端。
验证:
#include<iostream>
#include<cstdio>
#include<string>
#include<cassert>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<cstring>
using namespace std;
int main()
{
//创建管道文件,打开读写端
int fds[2];
int n=pipe(fds);
assert(n==0);
cout<<"fds[0]:"<<fds[0]<<endl;//读
cout<<"fds[1]:"<<fds[1]<<endl;//写
pid_t id=fork();
assert(id>=0);
if(id==0)
{
//子进程
close(fds[0]);
int cnt=0;
const char* s="我是子进程,我真正发消息";
while(true)
{
cnt++;
char buffer[1024];
snprintf(buffer,sizeof buffer,"child->parent: %s[%d][%d]\n",s,cnt,getpid());
write(fds[1],buffer,strlen(buffer));
sleep(1);
}
//子进程
close(fds[1]);//子进程关闭写端
cout<<"子进程关闭写端"<<endl;
exit(0);
}
//父进程的通信代码
close(fds[1]);
//父进程的通信代码
while(true)
{
char buffer[1024];
//把读到的内容当字符串处理
//如果管道中没有了数据,读端在读,默认会直接阻塞当前正在读取的进程。
ssize_t s=read(fds[0],buffer,sizeof(buffer)-1);
if(s>0)
{
buffer[s]=0;
cout<<"Get Message# "<<buffer<<"| my pid: "<<getpid()<<endl;
}
else if(s==0)
{
cout<<"read: "<<s<<endl;
break;
}
}
n=waitpid(id,nullptr,0);
assert(n==id);
//cout<<"hello c++"<<endl;
close(fds[0]);
return 0;
}